mIRC Home    About    Download    Register    News    Help

Print Thread
#266424 07/12/19 02:19 PM
Joined: Oct 2017
Posts: 47
D
Ameglian cow
OP Offline
Ameglian cow
D
Joined: Oct 2017
Posts: 47
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:

Code
//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: 5,411
Hoopy frood
Offline
Hoopy frood
Joined: Dec 2002
Posts: 5,411
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: 148
Vogon poet
Offline
Vogon poet
Joined: Dec 2015
Posts: 148
For fun:

$longipv6(<ip>) or /longipv6 <ip>
Code
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: 47
D
Ameglian cow
OP Offline
Ameglian cow
D
Joined: Oct 2017
Posts: 47
@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: 47
D
Ameglian cow
OP Offline
Ameglian cow
D
Joined: Oct 2017
Posts: 47
@Khaled,

What about this code? founded some examples in https://lite.ip2location.com/faqs

Code
#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,127
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 2,127
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:

Code
//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).


Link Copied to Clipboard