如何转换十六进制ipv6字符串分隔:在PostgreSQL中的十进制

时间:2018-03-18 17:28:40

标签: postgresql hex decimal ipv6

我正在尝试将十六进制字符串转换为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

如何获取实际的十进制数?

1 个答案:

答案 0 :(得分:0)

您的问题中的小数结果是您问题中十六进制数的正确结果。

您缺少的是第二个和第三个IPv6地址字中被抑制的前导零。您错误地将IPv6地址字符串表示形式(2001:200:101:ffff:ffff:ffff:ffff:ffff)转换为实际的十六进制数字(200102000101ffffffffffffffffffff)。注意添加的零位数。每个IPv6字是四个十六进制数字,但允许(RFC 5952要求)抑制字符串表示的单词中的前导零,但这并不意味着它们不存在。

在删除冒号之前,您需要确保每个IPv6地址字是四个十六进制数字(添加任何缺失的零以获得四位数,并用正确数量的0000字替换任何双冒号)。 / p>

似乎没有任何真正合法的理由将IPv6地址转换为十进制表示。 IP地址(IPv4和IPv6)都是二进制数,IPv6的十六进制表示直接转换为二进制数。将十进制添加到混合中只是在寻找麻烦。