我正在尝试将十六进制字符串转换为IPV6地址的NUMERIC列
十六进制输入为2001:200:101:ffff:ffff:ffff:ffff:ffff
我的输出应为42540528727106952925351778646877011967
我通过传递我的输入并尝试取消:
作为2001200101ffffffffffffffffffff
`CREATE OR REPLACE FUNCTION hex_to_int(hexval varchar) RETURNS numeric AS $$
DECLARE
result NUMERIC;
i integer;
len integer;
hexchar varchar;
BEGIN
result := 0;
len := length(hexval);
for i in 1..len loop
hexchar := substr(hexval, len - i + 1, 1);
result := result + 16 ^ (i - 1) * case
when hexchar between '0' and '9' then cast (hexchar as int)
when upper (hexchar) between 'A' and 'F' then ascii(upper(hexchar)) - 55
end;
end loop;
RETURN result;
END;
$$
LANGUAGE 'plpgsql' IMMUTABLE STRICT;`
我的小数是
select hex_to_int('2001200101ffffffffffffffffffff');
hex_to_int
--------------------------------------
166176317495821453702777150266933247
如何获取实际的十进制数?
答案 0 :(得分:0)
您的问题中的小数结果是您问题中十六进制数的正确结果。
您缺少的是第二个和第三个IPv6地址字中被抑制的前导零。您错误地将IPv6地址字符串表示形式(2001:200:101:ffff:ffff:ffff:ffff:ffff
)转换为实际的十六进制数字(200102000101ffffffffffffffffffff
)。注意添加的零位数。每个IPv6字是四个十六进制数字,但允许(RFC 5952要求)抑制字符串表示的单词中的前导零,但这并不意味着它们不存在。
在删除冒号之前,您需要确保每个IPv6地址字是四个十六进制数字(添加任何缺失的零以获得四位数,并用正确数量的0000
字替换任何双冒号)。 / p>
似乎没有任何真正合法的理由将IPv6地址转换为十进制表示。 IP地址(IPv4和IPv6)都是二进制数,IPv6的十六进制表示直接转换为二进制数。将十进制添加到混合中只是在寻找麻烦。