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

how to convert hexadecimal ipv6 string seperated by : to decimal in PostgreSQL

我正在尝试将十六进制字符串转换为 IPV6 地址的数字列 十六进制输入为2001:200:101:ffff:ffff:ffff:ffff:ffff 我的输出应该是 42540528727106952925351778646877011967 我通过消除 : as 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

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

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

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

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


似乎没有任何真实、合法的理由将 IPv6 地址转换为十进制表示形式。 IP 地址(IPv4 和 IPv6)都是二进制数,IPv6 的十六进制表示直接转换为二进制。将小数加到组合中只是自找麻烦。