A custom identifier to convert an IPv6 address to an integer and vice versa.
/*
{
$longipv6() by jaytea
This custom identifier is similar in usage to mIRC's own $longip(), but
handles IPv6 addresses instead of IPv4 ones.
Syntax: $longipv6(<IP/N>)
Takes in either a valid IPv6 address or a 128-bit unsigned integer and
performs a conversion between the two. Keep in mind that mIRC doesn't
normally handle numbers with 128 bits of precision, so this alias is
more limited in potential uses than its native $longip() counterpart.
Examples:
$longipv6(1) = ::1
$longipv6(12345678901234567890) = ::ab54:a98c:eb1f:ad2
$longipv6(::ab54:a98c:eb1f:ad2) = 12345678901234567890
$longipv6(ffff::) = 340277174624079928635746076935438991360
$longipv6(abc) = $null
Since 'abc' is neither a valid IPv6 address or a non-negative integer,
the result is $null. In general, if you are using an older version of
mIRC without $iptype(), if ($longipv6(%IP) isnum) is true and only true
when %IP is a valid IPv6 address.
}
*/
alias longipv6 {
if ($1-. isnum) {
if ($1 >= 0) {
var %num = $1, %i = 8, %out = :
while (%i) {
bunset "
bset " 50 0
while ($left(%num, 15) > 65535) {
var %div = $int($calc($v1 / 65536)), %rem = $v1 % 65536
bset -t " $calc(51 - $mid(%num, 16, 0) - $len(%div)) %div
%num = %rem $+ $mid(%num, 16)
}
%out = $+(:, $base(0 $+ $v1, 10, 16), %out)
!breplace " 0 48
%num = $regsubex($bvar(", 1-).text, /^0*/, )
dec %i
}
if ($version > 6.35) return $lower($iptype($mid(%out, 2, -1)).compress)
return $lower($regsubex(%out, /.$|((?:(:)0)++)(:$|(?(?!\1).)+(?=.$))|(((^)))./g, \2\3))
}
}
else {
if ($version > 6.35) {
if ($iptype($1-) != ipv6) return
}
elseif (!$regex($1-, /^(?(?=.*::)(?!(?>.*?:(?=:)){2})(::|(?>(?<=^|::)|:)[a-f\d]{1,4}+){1,8}+|(?1){8})$/)) return
; the above regular expression matches all valid IPv6 addresses
var %n, %i = 8, %out, $&
%3 = 281474976710656, $&
%4 = 18446744073709551616, $&
%5 = 1208925819614629174706176, $&
%6 = 79228162514264337593543950336, $&
%7 = 5192296858534827628530496329220096
if ($version > 6.35) %n = $iptype($1).expand
else %n = $replace($1, ::, $str(:0:, $calc(8 - $numtok($1, 58))))
while (%i) {
var %num = $base($gettok(%n, %i, 58), 16, 10), %pow = 8 - %i
if (%pow < 3) {
inc %out $calc(%num * 65536 ^ %pow)
}
elseif (%num) {
var %pow = $eval(% $+ %pow, 2), %carry, %result
while ($right(%pow, 10)) {
var %mul = $v1 * %num, %result = $base($calc($right(%mul, 10) + %carry), 10, 10, 10) $&
$+ %result, %carry = $left(%mul, -10), %pow = $left(%pow, -10)
}
var %result = %carry $+ %result, %carry, %num
while (%out $+ %result) {
var %add = $calc($right(%result, 15) + $right(%out, 15)), $&
%num = $base($calc($right(%add, 15) + %carry), 10, 10, 15) $+ %num, $&
%carry = $left(%add, -15), %out = $left(%out, -15), %result = $left(%result, -15)
}
%out = %carry $+ %num
}
dec %i
}
return $regsubex(%out, /^0*+\B/, )
}
}