Quantos endereços IP estão em um determinado intervalo?

31

Inspirado por...

Rede - Como posso calcular quantos endereços IP existem em um determinado intervalo?

Escreva um programa ou função que use duas cadeias de caracteres como entrada, cada uma sendo um endereço IPv4 expresso em notação pontilhada padrão e produz ou retorna o número de endereços IP cobertos por esse intervalo, incluindo as duas entradas de endereços IP.

  • Você não deve usar nenhum código externo, bibliotecas ou serviços projetados para analisar um endereço IP. (Outras funções da biblioteca padrão de processamento de string são aceitáveis.)
  • Todos os 2 ^ 32 endereços IP são iguais. Nenhuma distinção é feita para transmissão, classe E etc.
  • Aplicam-se regras normais de código-golfe.

Por exemplo:

"0.0.0.0","255.255.255.255" returns 4294967296.
"255.255.255.255","0.0.0.0" also returns 4294967296.
"1.2.3.4","1.2.3.4" returns 1.
"56.57.58.59","60.61.62.63" returns 67372037.
"1","2" is invalid input. Your code may do anything you like.
billpg
fonte
Eu vi essa pergunta nos programadores e estava pensando em fazer isso no código golf lol.
Cruncher
3
Eu pensei que esta é uma pergunta StackOverflow sobre quais endereços IP são impossíveis de acordo com os padrões.
Ming-Tang
8
O IPv4 não é um pouco ultrapassado?
Ugoren 31/05

Respostas:

20

GolfScript, 20 bytes

~]7/${2%256base}/)\-

Experimente online.

Casos de teste

$ echo 0.0.0.0 255.255.255.255 | golfscript range.gs
4294967296
$ echo 255.255.255.255 0.0.0.0 | golfscript test.gs
4294967296
$ echo 1.2.3.4 1.2.3.4 | golfscript test.gs
1
$ echo 56.57.58.59 60.61.62.63 | golfscript test.gs
67372037

Como funciona

~]        # Evaluate and collect into an array.
          #
          # “.” duplicates, so for "5.6.7.8 1.2.3.4", this leaves
          # [ 5 5 6 6 7 7 8 1 1 2 2 3 3 4 ] on the stack.
          #
7/        # Split into chunks of length 7: [ [ 5 5 6 6 7 7 8 ] [ 1 1 2 2 3 3 4 ] ]
$         # Sort the array of arrays: [ [ 1 1 2 2 3 3 4 ] [ 5 5 6 6 7 7 8 ] ]
{         # For each array:
  2%      # Extract every second element. Example: [ 1 2 3 4 ]
  256base # Convert the IP into an integer by considering it a base 256 number.
}/        #
)         # Add 1 to the second integer.
\-        # Swap and subtract. Since the integers were sorted, the result is positive.
Dennis
fonte
Uso muito agradável e agradável de $evitar abs.
Chris Jester-Young
4
~]também é realmente inteligente.
Primo 30/05
10

Python 2-106

Veja aqui .

def a():x=map(int,raw_input().split("."));return x[0]*2**24+x[1]*2**16+x[2]*2**8+x[3]
print abs(a()-a())+1

Exemplo de entrada

0.0.0.0
0.0.0.255

Saída de exemplo

256

Rainbolt
fonte
1
def a():return reduce(lambda c,d:c*256+d,map(int,raw_input().split(".")))é muito menor
Michael M.
5
@ Michael Obrigado pela sugestão. Usei-o por alguns minutos, depois olhei e pensei: "Não escrevi 90% disso". então eu rolei de volta.
Rainbolt
@ Michael a=lambda:em vez de def a():return salva 6 caracteres
avall
@Rusher São 107 caracteres, não 106
avall
1
@ avall: Eu suponho que você está contando o LF final.
Dennis
8

CJam - 15

{r'./256b}2*-z)

Experimente em http://cjam.aditsu.net/

Obrigado Dennis, uau, não sei como tirar o melhor proveito do meu próprio idioma: p

aditsu
fonte
Você pode salvar dois bytes, eliminando :i( bparece elenco para inteiro) e um usando {r...}2*em vez deqS/{...}/
Dennis
6

Festa pura, 66 bytes

p()(printf %02x ${1//./ })
r=$[0x`p $1`-0x`p $2`]
echo $[1+${r/-}]

Notas:

  • Define uma função pque recebe um endereço IP decimal pontilhado e gera a representação hexadecimal desse endereço:
    • ${1//./ }é uma expansão de parâmetro que substitui .por no endereço IP passado parap()
    • O printfé principalmente auto-explicativo. Como existe apenas um especificador de formato %02xe quatro args restantes, o especificador de formato é reutilizado para cada arg restante, concatenando efetivamente os 2 dígitos hexadecimais de cada um dos 4 octetos juntos
  • $[]causa expansão aritmética. Fazemos uma subtração básica e atribuímos à variávelr
  • ${r/-}é uma expansão de parâmetro para remover um -caractere possível - efetivamente abs ()
  • Exiba 1 + a diferença absoluta para fornecer o intervalo.

Saída:

$ ./iprangesize.sh 0.0.0.0 255.255.255.255
4294967296
$ ./iprangesize.sh 255.255.255.255 0.0.0.0
4294967296
$ ./iprangesize.sh 1.2.3.4 1.2.3.4
1
$ ./iprangesize.sh 56.57.58.59 60.61.62.63
67372037
$ ./iprangesize.sh 1 2
2
$ 
Trauma Digital
fonte
Eu detecto printfe echo. Isso faz parte bash?
CalculatorFeline
1
@CatsAreFluffy Eles estão embutidos.
fase
6

Python 2.7 - 96 91 90 87

Fez uma função.

f=lambda a:reduce(lambda x,y:x*256+int(y),a.split("."),0)
p=lambda a,b:abs(f(a)-f(b))+1

Uso:

>>> p("1.2.3.4","1.2.3.5")
2

Edit: Removido desnecessariamente int()da ffunção. Graças a isaacg

Edit2: removido LFno final do arquivo (graças a @Rusher) e removido map()ao custo do reduce()inicializador (graças a @ njzk2)

avall
fonte
1
por que a função f precisa de int () do lado de fora?
Isaacg
1
Bem. Eu não tinha ideia: D
avall
pode ganhar 2 caracteres por colocar o int no reduzir em vez de usar o mapa (apenas 2, conforme você precisa adicionar ,0parâmetro para sua função de reduzir)
njzk2
Acabei de escrever algo que é quase exatamente o seu código, então não vou me incomodar em enviar agora. Na verdade, o meu tem três caracteres a mais!
21415 Danmcardle
5

GolfScript, 27 bytes

' '/{'.'/{~}%256base}/-abs)

Exemplos:

$ echo 0.0.0.0 255.255.255.255 | ruby golfscript.rb iprange.gs
4294967296
$ echo 255.255.255.255 0.0.0.0 | ruby golfscript.rb iprange.gs
4294967296
$ echo 1.2.3.4 1.2.3.4 | ruby golfscript.rb iprange.gs
1
$ echo 56.57.58.59 60.61.62.63 | ruby golfscript.rb iprange.gs
67372037
Chris Jester-Young
fonte
2
Você pode salvar um caractere usando em /vez de %~.
Dennis
4

CoffeeScript - 94, 92, 7972

I=(a)->a.split(".").reduce((x,y)->+y+x*256)
R=(a,b)->1+Math.abs I(b)-I a

Sem golfe :

I = ( a ) ->
    return a.split( "." ).reduce( ( x, y ) -> +y + x * 256 )

R = ( a, b ) ->
    return 1 + Math.abs I( b ) - I( a )

JavaScript equivalente :

function ip2long( ip_str )
{
    var parts = ip_str.split( "." );    
    return parts.reduce( function( x, y ) {
        return ( +y ) + x * 256; //Note: the unary '+' prefix operator casts the variable to an int without the need for parseInt()
    } );
}

function ip_range( ip1, ip2 )
{
    var ip1 = ip2long( ip1 );
    var ip2 = ip2long( ip2 );

    return 1 + Math.abs( ip2 - ip1 );
}

Experimente online .

Tony Ellis
fonte
1
Você pode salvar alguns caracteres substituindo alguns parênteses por espaços:I=(a)->n=0;a.split(".").forEach((x)->n<<=8;n+=parseInt x);n>>>0 R=(a,b)->1+Math.abs I(b)-I a
Rob W
Parece que você está perdendo muito espaço Math.abs, mas não consigo pensar em nada mais curto. (z>0)*z||-zé o melhor que eu tenho (mesmo comprimento e precisa de uma entrada de caractere único). Você tem algo mais inteligente que isso?
Aaron Dufour
esta versão javascript realmente me ajuda, eu estou procurando por isso há uma hora. obrigado!
nodeffect
4

dc, 61 caracteres

?[dXIr^*rdXIr^*256*+r1~dXIr^*r256*+65536*+]dspxsalpxla-d*v1+p

Eu acho incrível que isso possa ser resolvido com dc, uma vez que não tem capacidade de analisar seqüências de caracteres. O truque é que 192.168.123.185 entra na pilha como

.185
.123
192.168

e dXIr^*desloca o ponto decimal para a direita quantos dígitos de fração houver e até funciona para 0,100.

$ echo 56.57.58.59 60.61.62.63 | dc -e '?[dXIr^*rdXIr^*256*+r1~dXIr^*r256*+65536*+]dspxsalpxla-d*v1+p'
67372037.00

Subtraia um caractere se você deixar a entrada já estar na pilha.

Geoff Reedy
fonte
4

Powershell - 112 108 92 78 bytes

Esta é a minha primeira vez jogando golfe. Aqui vai nada:

Golfe (Antigo):

$a,$b=$args|%{$t='0x';$_-split'\.'|%{$t+="{0:X2}"-f[int]$_};[uint32]$t};1+[math]::abs($a-$b)

Golfe (novo)

$a,$b=$args|%{$t='0x';$_-split'\.'|%{$t+="{0:X2}"-f+$_};[long]$t}|sort;1+$b-$a

Ungolfed:

$a, $b = $args | % {           #powershell's way of popping an array. In a larger array
                               #$a would equal the first member and $b would be the rest.
    $t = '0x';                 #string prefix of 0x for hex notation
    $_ -split '\.' | % {       #split by escaped period (unary split uses regex)
        $t += "{0:X2}" -f +$_  #convert a dirty casted int into a hex value (1 octet)
    };
    [long]$t                   #and then cast to long
} | sort;                      #sort to avoid needing absolute value
1 + $b - $a                    #perform the calculation

Uso

Salve como arquivo (neste caso, getipamount.ps1) e depois ligue do console

getipamount.ps1 255.255.255.255 0.0.0.0
SomeShinyMonica
fonte
4

C # com LINQ - 139 bytes

(A partir de 140 depois de aplicar a sugestão de Bob.)

long f(params string[] a){return Math.Abs(a.Select(b=>b.Split('.').Select(long.Parse).Aggregate((c,d)=>c*256+d)).Aggregate((e,f)=>e-f))+1;}

Ungolfed ....

    long f(params string[] a)                           // params is shorter than two parameters.
    {
        return Math.Abs(                                // At the end, make all values +ve.
             a.Select(                                  // Go through both items in the array...
                b =>                                    // Calling each one 'b'. 
                    b.Split('.')                        // Separating out each "." separated byte...
                    .Select(long.Parse)                 // Converting them to a long.
                    .Aggregate((c, d) => c*256 + d)     // Shift each byte along and add the next one.
             )
             .Aggregate((e,f) => e-f)                   // Find the difference between the two remaining values.
         )+1;                                           // Add one to the result of Math.Abs.
    }

https://dotnetfiddle.net/XPTDlt

billpg
fonte
Alguém poderia me explicar como todo esse deslocamento de bytes funciona?
Obversity
@Oversversity a.b.c.dé equivalente a (a << 24) | (b << 16) | (c << 8) | (d << 0)é equivalente a (((a << 8) << 8) << 8) + ((b << 8) << 8) + (c << 8) + d). Basicamente, cada iteração da agregação pega a soma existente e a desloca para a esquerda em um octeto, depois adiciona o próximo octeto.
Bob
Você pode salvar um personagem usando em c*256vez de (c<<8).
Bob
@ Bob Bem avistado.
billpg
Você pode salvar mais dois personagens, substituindo e-fcom e<f?f-e:e-fe soltando aMath.Abs()
Patrick Huizinga
4

Perl, 43 bytes

#!perl -pa
$_=1+abs${\map{$_=vec eval,0,32}@F}-$F[0]

Contando o shebang como dois bytes.

Uso da amostra:

$ echo 0.0.0.0 255.255.255.255 | perl count-ips.pl
4294967296

$ echo 255.255.255.255 0.0.0.0 | perl count-ips.pl
4294967296

$ echo 56.57.58.59 60.61.62.63 | perl count-ips.pl
67372037

Notas

  • vec eval,0,32é um exemplo para ip2long. O Perl permite que os literais de caracteres sejam expressos como seu prefixo ordinal com a v, por exemplo, v0pode ser usado para o caractere nulo. Estes também podem ser encadeados, por exemplo v65.66.67.68ABCD. Quando três ou mais valores estão presentes, a inicial vé desnecessária. A vecfunção interpreta uma string como uma matriz inteira, cada célula com o número especificado de bits (aqui, 32). unpack N,evalteria funcionado igualmente também.
primo
fonte
3

JavaScript ES6 - 68 bytes

f=x=>prompt().split('.').reduce((a,b)=>+b+a*256);1+Math.abs(f()-f())

Experimente com o console (pressione F12) do Firefox.

Michael M.
fonte
Você deveria estar usando alertou console.log. A saída do console é barata.
Ndscore 29/05
4
@ Underscore, absolutamente nenhuma diferença entre console.loge saída direta. Isso é código-golfe, não se trata de código limpo.
Michael M.
A resposta mais votada para esta meta postagem discorda: JavaScript Standards for IO . Não é uma questão de código limpo. É uma questão de realmente não produzir nada.
Ndscore 29/05
@DigitalTrauma, não funcionará devido à precedência do operador . (adição vs deslocamento bit a bit)
Michael M.
2

Python 2.7, 104 bytes

y=lambda:map(int,input().split("."));a,b=y(),y();print sum(256**(3-i)*abs(a[i]-b[i])for i in range(4))+1
Pablo Lucena
fonte
1
Obrigado pela solução. Você acha que pode: 1. Alternar de ponto e vírgula para novas linhas, para facilitar a leitura sem sacrificar o comprimento. 2. Explique como o código funciona?
Isaacg
2

Perl, 72 bytes

#!perl -ap
@a=map{unpack N,pack C4,split/\./,$_}@F;$_=abs($a[1]-$a[0])+1

Uso:

$ echo 10.0.2.0 10.0.3.255 | perl ip-range.pl
512$ 

Isso já é mais longo que o programa Perl do primo , então não é muito interessante.

Perl, 119 bytes, para formato de endereço IP obsoleto

#!perl -ap
sub v(){/^0/?oct:$_}@a=map{$m=3;@p=split/\./,$_;$_=pop@p;$s=v;$s+=v<<8*$m--for@p;$s}@F;$_=abs($a[1]-$a[0])+1

Uso:

$ echo 10.0.2.0 10.0.3.255 | perl ip-obsolete.pl
512$ 
$ echo 10.512 10.1023 | perl ip-obsolete.pl
512$ 
$ echo 0xa.0x200 012.01777 | perl ip-obsolete.pl 
512$ 

Este programa aceita o formato obsoleto para endereços IP! Isso inclui endereços com 1, 2 ou 3 partes ou com partes hexadecimal ou octal. Citando a página de manual inet_addr (3) ,

Os valores especificados usando a notação de ponto assumem uma das seguintes formas:

a.b.c.d
a.b.c
a.b
a

... Quando um endereço de três partes é especificado, a última parte é interpretada como uma quantidade de 16 bits e colocada nos dois bytes mais à direita do endereço de rede. ... Quando um endereço de duas partes é fornecido, a última parte é interpretada como uma quantidade de 24 bits e colocada nos três bytes mais à direita do endereço de rede. ... Quando apenas uma parte é fornecida, o valor é armazenado diretamente no endereço de rede sem nenhum rearranjo de bytes.

Todos os números fornecidos como `` partes '' em uma notação de ponto podem ser decimais, octais ou hexadecimais, conforme especificado no idioma C (ou seja, um 0x ou 0X inicial implica hexadecimal; um 0 inicial implica octal; caso contrário, o número é interpretado como decimal).

Muitos programas não aceitam mais esse formato obsoleto, mas ping 0177.1ainda funcionam no OpenBSD 5.5.

Kernigh
fonte
O fato de você estar usando o BSD é mais surpreendente do que o IP.
fase
2

PHP, 138 110 bytes

<?php

function d($a,$b){foreach(explode('.',"$a.$b")as$i=>$v){$r+=$v*(1<<24-$i%4*8)*($i<4?1:-1);}return 1+abs($r);}

// use it as
d('0.0.0.0','255.255.255.255');
Vitaly Dyatlov
fonte
Como não há menção a 'sem avisos de descontinuação', você pode salvar um caractere substituindo-o explode('.',"$a.$b")por split('\.',"$a.$b").
precisa saber é o seguinte
Conto 109, não 110. Salve 9 bytes com um programa em vez de uma função e mais 8 com estas etapas de golfe: sandbox.onlinephpfunctions.com/code/…
Titus
1

Mathematica 9, 108 bytes

c[f_,s_]:=1+First@Total@MapIndexed[#1*256^(4-#2)&,First@Abs@Differences@ToExpression@StringSplit[{f,s},"."]]

Ungolfed:

countIpAddresses[first_, second_] := Module[{digitArrays, differences},

  (* Split the strings and parse them into numbers. 
  Mathematica automatically maps many/most of its functions across/
  through lists *)

  digitArrays = ToExpression[StringSplit[{first, second}, "."]];

  (* Find the absolute value of the differences of the two lists, 
  element-wise *)
  differences = Abs[Differences[digitArrays]];

  (* differences looks like {{4, 4, 4, 4}} right now, 
  so take the first element *)
  differences = First[differences];

  (* now map a function across the differences, 
  taking the nth element (in code, '#2') which we will call x (in 
  code, '#1') and setting it to be equal to (x * 256^(4-n)). 
  To do this we need to track the index, so we use MapIndexed. 
  Which is a shame, 
  because Map can be written '/@' and is generally a huge character-
  saver. *)
  powersOf256 = MapIndexed[#1*256^(4 - #2) &, differences];

  (* now we essentially have a list (of singleton lists, 
  due to MapIndexed quirk) which represents the digits of a base-256, 
  converted to decimal form. 
  Example: {{67108864},{262144},{1024},{4}}

  We add them all up using Total, 
  which will give us a nested list as such: {67372036}

  We need to add 1 to this result no matter what. But also, 
  to be fair to the challenge, we want to return a number - 
  not a list containing one number. 
  So we take the First element of our result. If we did not do this, 
  we could chop off 6 characters from our code. *)

  1 + First[Total[powersOf256]]
]
Ian Douglas
fonte
0

C # - 135

long f(string x,string y){Func<string,long>b=s=>s.Split('.').Select((c,i)=>long.Parse(c)<<(3-i)*8).Sum();return Math.Abs(b(x)-b(y))+1;}

Devidamente formatado

long g(string x, string y) { 
    Func<string, long> b = s => s.Split('.').Select((c, i) => long.Parse(c) << (3 - i) * 8).Sum(); 
    return Math.Abs(b(x) - b(y)) + 1; 
}

https://dotnetfiddle.net/Q0jkdA

tia
fonte
0

Ruby, 93 bytes

a=->(x){s=i=0;x.split('.').map{|p|s+=256**(3-i)*p.to_i;i+=1};s}
s=->(x,y){1+(a[x]-a[y]).abs}

Saída

irb(main):003:0> s['1.1.1.1', '1.1.1.2']
=> 2
irb(main):006:0> s['0.0.0.0', '255.255.255.255']
=> 4294967296
bsd
fonte
0

J, 25 bytes

Aceita as seqüências IP de quatro pontos como argumentos à esquerda e à direita.

>:@|@-&(256#.".;.2@,&'.')

Explicado:

>:@|@-&(256#.".;.2@,&'.')  NB. ip range
      &(                )  NB. on both args, do:
                   ,&'.'   NB.   append a .
               ;.2@        NB.   split by last character:
             ".            NB.     convert each split to number
        256#.              NB. convert from base 256
   |@-                     NB. absolute difference
>:@                        NB. add 1 to make range inclusive

Exemplos:

   '0.0.0.0' >:@|@-&(256#.".;.2@,&'.') '255.255.255.255'
4294967296
   iprange =: >:@|@-&(256#.".;.2@,&'.')
   '255.255.255.255' iprange '0.0.0.0'
4294967296
   '1.2.3.4' iprange '1.2.3.4'
1
   '56.57.58.59' iprange '60.61.62.63'
67372037
algoritmshark
fonte
0

Fator, 73 bytes

Tradução da resposta do CoffeeScript.

[ "." split [ 10 base> ] [ [ 256 * ] dip + ] map-reduce ] bi@ - abs 1 + ]
gato
fonte
0

Javascript ES6, 81 caracteres

(a,b)=>Math.abs(eval(`(((((${a})>>>0)-(((((${b})>>>0)`.replace(/\./g,")<<8|")))+1

Teste:

f=(a,b)=>Math.abs(eval(`(((((${a})>>>0)-(((((${b})>>>0)`.replace(/\./g,")<<8|")))+1
;`0.0.0.0,255.255.255.255,4294967296
255.255.255.255,0.0.0.0,4294967296
1.2.3.4,1.2.3.4,1
56.57.58.59,60.61.62.63,67372037`.split`
`.map(x=>x.split`,`).every(x=>f(x[0],x[1])==x[2])

PS: Vou tentar otimizá-lo um pouco mais tarde.

Qwertiy
fonte
0

Lua, 153 bytes

É uma pena que lua não tenha uma função dividida, tive que definir a minha!

a,b=...r=0y=8^8x={}t={}function f(t,s)s:gsub("%d+",function(d)t[#t+1]=d end)end
f(x,a)f(t,b)for i=1,4 do r=r+y*math.abs(t[i]-x[i])y=y/256 end print(r+1)

Ungolfed

a,b=...                    -- unpack the arguments into two variables
r=0                        -- initialise the sume of ip adress
y=8^8                      -- weight for the rightmost value
x={}t={}                   -- two empty arrays -> will contains the splittedip adresses
function f(t,s)            -- define a split function that takes:
                           --   a pointer to an array
                           --   a string
  s:gsub("%d+",function(d) -- iterate over the group of digits in the string
    t[#t+1]=d              -- and insert them into the array
  end)
end
f(x,a)                     -- fill the array x with the first address
f(t,b)                     -- fill the array t with the second address
for i=1,4                  -- iterate over t and x
do
  r=r+y*math.abs(t[i]-x[i])-- incr r by weight*abs(range a- range b)
  y=y/256                  -- reduce the weight
end
print(r+1)                 -- output the result
Katenkyo
fonte
0

Geléia , 12 bytes, desafio pós-datas de idiomas

ṣ”.V€ḅ⁹µ€ạ/‘

Experimente online!

Explicação

ṣ”.V€ḅ⁹µ€ạ/‘
       µ€     On each element of input:
ṣ”.             Split on periods
   V€           Convert string to number in each section
     ḅ⁹         Convert base 256 to integer
         ạ/   Take absolute difference of the resulting integers
           ‘  Increment

O número de elementos em um intervalo inclusivo é a diferença absoluta de seus pontos de extremidade, mais 1.


fonte
0

Axioma, 385 bytes

c(a:String):INT==(d:=digit();s:NNI:=#a;t:INT:=0;for i in 1..s repeat(~member?(a.i,d)=>return-1;t:=t+(ord(a.i)-48)*10^(s-i)::NNI);t)
g(x:String):List NNI==(a:=split(x,char".");s:NNI:=#a;r:=[];for i in s..1 by -1 repeat(y:=c(a.i);y=-1=>return [];r:=concat(y,r));r)
m(x:NNI,y:NNI):NNI==x*256+y
f(a:String,b:String):INT==(x:=g(a);y:=g(b);#x~=4 or #y~=4=>-1;1+abs(reduce(m,x)-reduce(m,y)))

ungolf-lo e testar

-- convert the string only digit a in one not negative number
-- return -1 in case of error
cc(a:String):INT==
     d:=digit();s:NNI:=#a;t:INT:=0
     for i in 1..s repeat
               ~member?(a.i,d)=>return -1
               t:=t+(ord(a.i)-48)*10^(s-i)::NNI
     t

-- Split the string x using '.' as divisor in a list of NNI
-- if error return []
gg(x:String):List NNI==
    a:=split(x,char".");s:NNI:=#a;r:=[]
    for i in s..1 by -1 repeat
          y:=cc(a.i)
          y=-1=>return []
          r:=concat(y,r)
    r


mm(x:NNI,y:NNI):NNI==x*256+y

-- Return absolute value of difference of address for IP strings in a and in b 
-- Retrun -1 for error
-- [Convert the IP strings in a and in b in numbers ad subtract and return the difference]
ff(a:String,b:String):INT==(x:=gg(a);y:=gg(b);#x~=4 or #y~=4=>-1;1+abs(reduce(mm,x)-reduce(mm,y)))


(14) -> f("0.0.0.0", "255.255.255.255")
   (14)  4294967296
                                                    Type: PositiveInteger
(15) -> f("255.255.255.255", "0.0.0.0")
   (15)  4294967296
                                                    Type: PositiveInteger
(16) -> f("1.2.3.4", "1.2.3.4")
   (16)  1
                                                    Type: PositiveInteger
(17) -> f("56.57.58.59", "60.61.62.63")
   (17)  67372037
                                                    Type: PositiveInteger
(18) -> f("1", "2")
   (18)  - 1
                                                            Type: Integer
RosLuP
fonte