|
Joined: Oct 2017
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Oct 2017
Posts: 40 |
Hello and Greetings from Konzentrationslager, I am not sure if this is 100% a bug or a missing feature, when I use $longip() with ipv6 address as input it doesn't return the correct value, this happens only in IPV6 addresses thought. Example: //echo -a Result: $longip(2a01:7e01::f03c:91ff:fefd:d84) NOTE: I tested the results to compare them using https://www.ipaddressguide.com/ipv6-to-decimal website but I saw that mirc had a problem when using ipv6 as input on that identifier.
Last edited by DooMaster; 07/12/19 02:20 PM.
|
|
|
|
Joined: Dec 2002
Posts: 3,840
Hoopy frood
|
Hoopy frood
Joined: Dec 2002
Posts: 3,840 |
The scripting language can handle 32bit values in most features and double values in calculations, such as in $calc(). It cannot handle 64bit values or larger. An IPv6 address is a 128bit value. While it would be possible to update $longip() to return a 128bit value in this specific case, the result would be unusable anywhere else in the scripting language. This means that if you need to manipulate 128bit values, you will need to write your own methods to do this.
|
|
|
|
Joined: Dec 2015
Posts: 147
Vogon poet
|
Vogon poet
Joined: Dec 2015
Posts: 147 |
For fun: $longipv6(<ip>) or /longipv6 <ip> alias longipv6 {
bset -t & 1 $1
set -l %start 1
set -l %end
set -l %hextets
while ($bfind(&,%start,:).textcs) {
%end = $v1 - 1
if (%end > %start) %hextets = %hextets $base($bvar(&,%start - %end).text,16,10)
else %hextets = %hextets SHORTENED
%start = %end + 2
}
tokenize 32 $replacex(%hextets $base($bvar(&,%start -).text,16,10),SHORTENED,$str(0 $+ $chr(32),$calc(8 - $numtok(%hextets,32))))
set -l %decimal $add_($multiply_(5192296858534827628530496329220096,$1),$multiply_(79228162514264337593543950336,$2))
%decimal = $add_(%decimal,$multiply_(1208925819614629174706176,$3))
%decimal = $add_(%decimal,$multiply_(18446744073709551616,$4))
%decimal = $add_(%decimal,$multiply_(281474976710656,$5))
%decimal = $add_(%decimal,$multiply_(4294967296,$6))
%decimal = $add_(%decimal,$multiply_(65536,$7))
$iif($isid,return,echo -a) $add_(%decimal,$8)
}
alias add_ {
if ($len($2) > $len($1)) tokenize 32 $2 $1
set -l %result
set -l %carryover
set -l %temp
while ($right($1,15) isnum) {
%temp = $base($calc($v1 + $right($2,15) + %carryover),10,10,$len($v1))
%carryover = $mid(%temp,1-,-15)
%result = $right(%temp,15) $+ %result
tokenize 32 $mid($1,1-,-15) $mid($2,1-,-15)
}
return %result
}
alias multiply_ {
if ($len($2) > $len($1)) tokenize 32 $2 $1
set -l %temp
set -l %result
set -l %multiplicand $1
set -l %multiplier
set -l %remaining
set -l %interval
set -l %padding
set -l %carryover
tokenize 1 $2
while ($1 isnum) {
%multiplier = $right($1,7)
%remaining = $mid($1,1-,-7)
%carryover = 0
if (%multiplier > 0) {
tokenize 1 %multiplicand
while ($right($1,7) isnum) {
%temp = $base($calc($v1 * %multiplier + %carryover),10,10,$len($v1))
%carryover = $mid(%temp,1-,-7)
%interval = $right(%temp,7) $+ %interval
tokenize 1 $mid($1,1-,-7)
}
if (%carryover) %interval = %carryover $+ %interval
%result = $add_(%result,%interval $+ %padding)
}
%padding = %padding $+ $str(0,$len(%multiplier))
tokenize 1 %remaining
}
return %result
} It checks absolutely nothing, you can literally feed it carrots and it won't even blink an eye. Seriously, carrots: /longipv6 carrots
Last edited by Dazuz; 07/12/19 08:14 PM. Reason: Brain fart
|
|
|
|
Joined: Oct 2017
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Oct 2017
Posts: 40 |
@Dazuz,
Thanks for the code! It works, at least there is an alternative...
Last edited by DooMaster; 07/12/19 08:42 PM.
|
|
|
|
Joined: Oct 2017
Posts: 40
Ameglian cow
|
OP
Ameglian cow
Joined: Oct 2017
Posts: 40 |
@Khaled, What about this code? founded some examples in https://lite.ip2location.com/faqs#include <arpa/inet.h>
#include <inttypes.h>
typedef unsigned __int128 uint128_t;
uint128_t Dot2LongIP(const char* ipv6) {
struct sockaddr_in6 sa;
inet_pton(AF_INET6, ipv6, &(sa.sin6_addr));
uint128_t ipnum = 0;
uint128_t octet = 0;
int i;
for (i = 0; i < (sizeof(sa.sin6_addr.s6_addr) / sizeof(sa.sin6_addr.s6_addr[0])); i++) {
octet = ((uint128_t)sa.sin6_addr.s6_addr[i] << ((uint128_t)(15 - i) * 8));
ipnum = ipnum + octet;
}
return ipnum;
}
Last edited by DooMaster; 07/12/19 09:27 PM.
|
|
|
|
Joined: Jan 2004
Posts: 2,081
Hoopy frood
|
Hoopy frood
Joined: Jan 2004
Posts: 2,081 |
If $longip were to support ipv6, it would need to have either a switch or .prop to confirm whether the $longip(integer) output should be translated to ipv4 or ipv6, not simply by inspecting whether the integer is >= 2^32. Current behavior is that the integer is modulo 2^32 when it's >= 2^32. Since /bset doesn't have a way to directly store .nlong values, it's possible for scripts to be using $longip as a shortcut for storing byte values into a binvar like this, without first using $calc(number % 2^32) to sanitize in case the %a value is above 2^32: //var %a 987654321 | bset -c &v 1 $replace($longip(%a),.,$chr(32)) | echo -a $bvar(&v,1-) -> $bvar(&v,1).nlong
As for mIRC supporting values greater than 2^53, a happy-medium would be to assume that the vast majority of users wanting support above 2^53 are only interested in integer outputs, so some kind of $BigIntegerCalc which uses one of the BigInteger classes to output only integers would solve much of what people are looking for. The input could either require input parms to be integers, treat non-integer inputs as zero terms, or chop fractions off inputs. Each intermediate result within the calculation would also be chopped to integer, regardless whether or not parenthesis are used, so / and // would be equivalent. With a minor amount of extra logic, the output could also support negative outputs if the Big Integer class didn't support negatives. Theoretically, a Big Integer class could handle outputs limited only by $maxlenl or the time your script can wait for the calculated result. $longip isn't the only place besides $calc where integer values above 2^53 are useful. Logical functions like $and or $xor aren't valid for inputs above 2^32-1, and trying to use $calc to implement them on larger values between 2^32 and 2^53 can get complex. If these are hooked to $bigintegercalc, functions like $isbit could work above 32. $base currently doesn't provide valid output for inputs whose base10 equivalent is greater than 2^53. ie. $base($base(deadbeefdeadbeef,16,10),10,16). Translating hex strings using $base is limited to 13 digits. $base($str(f,13),16,36) The HOTP protocol supported by $hotp has a 'count' parameter that's intended to support a 64-bit integer value which can be incremented and wrap the incremented values modulo 2^64. But with the doubles limit of $calc, $calc(number +1) stops incrementing at 2^53, and for some higher values can return an output lesser than the input. $rand is using JSF64 which outputs a perfectly good 64-bit value, but is being limited into the 2^53 doubles range, so it can return out-of-range outputs like from $rand(9007199254740993,9007199254740993).
|
|
|
|
|