IPv6地址的算术运算(大整数)

4

我正在处理以以下形式表示的IPv6地址:

FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF

在内部,我将它们存储在一个数组中:

TIp6Bytes = array [0..15] of Byte;

我需要以多种方式操作IPv6地址,包括添加、分割、乘等。有人能推荐一种好的方法吗?

我猜我应该提到我正在使用Delphi 2009。


为什么不将它们作为2D数组内部存储呢?8x2字节,就像IPv4地址被处理为4x1字节一样。 - Andrew Coleson
我正在使用Synapse中使用的相同类型,这样我就可以使用它已经提供的多个函数。不确定为什么他们不将其存储为8x2,但事实就是如此 :) - norgepaul
1
我的IP库已经更新,它可以使用字符串输入和输出进行正确的IP数学计算,并带有一些类函数。它使用了许多验证,甚至使用了压缩、混合和压缩混合IPv6地址。该库被用于IPvX计算器中。 - Ron Maupin
4个回答

4

这里有一个用于Pascal的大数单位,Jes Klinke在这里编写了它。

免责声明:我个人没有使用过此库。


哇...处理Int128、Int256...一直到Int3k,再加上一些备用的。:) 很好的发现,看起来它可以很好地解决问题,尽管我还没有深入研究这些部分。 (+1 希望我能给更多) - skamradt
我尝试使用这个库,但减法函数中存在一个重大的错误。我试图联系作者,但没有收到回复。请查看我的答案以获取另一种选择。 - norgepaul

3

我曾经编写过一个IPv4和IPv6转换单元,其中包括了两种类型的IP地址的自定义变量类型。

例如,使用这些变量类型,可以进行以下示例算术运算和转换:

procedure TForm1.Button1Click(Sender: TObject);
var
  I4: TIPv4;
  I6: TIPv6;
  V1, V2, V3, V4: Variant;
begin
  I4 := StrToIPv4('192.0.2.128');
  I6 := IPv4ToIPv6(I4);
  V1 := VarIPv6Create('2001:db8:85a3:0:0:8a2e:0370:7334');
  V2 := IPv6ToVar(I6);
  V3 := V1 - V2;
  V4 := V1 or V2;
  if V3 < V4 then
    Log(V3 + ' is smaller than ' + V4);
  if V2.Equals('::ffff:192.0.2.128') or V2.IsZero then
    Log('OK');
  Log('V1 = ' + V1.AsStringOutwritten);
  Log('V2 = ' + V2.AsURL);
  Log('V3 = ' + V3.AsStringCompressed);
  V4.Follow;
end;

procedure TForm1.Log(const S: String);
begin
  Memo.Lines.Add(S);
end;

自定义变体类型确实非常强大。


我已经下载了你的IPv4和IPv6转换单元,首先我要祝贺你的工作,它非常出色。现在你的单元中真正缺少的是一个函数来验证某个IPv6地址是否在IPv6子网的范围内或外部。类似于IsInIPv6Subnet('2001:db8:4000:0123:ac45::01ff','2001:db8:4000::/36')。有计划添加这样的函数吗? - FjodrSo

3
在尝试了许多建议后,我找不到一个满足我所有需求并且没有错误的库。我更加努力地搜索,发现了一个相对较新的Alex Ciobanu库,它可以无缝地处理BigIntegers(和Big Cardinals),允许您以与操作普通整数、Cardinals等类似的方式操纵它们。
除了BigIntegers外,该库还提供了许多非常有用的功能。从自述文件中可以看出:
- 一组通用的集合类(List、Dictionary、HashSet等)。 - 将日期/时间功能组合在几个结构中(在某种程度上相当于.NET的DateTime结构)。 - 类型支持概念,为每个内置的Delphi类型定义了一组默认的“支持类”(在集合中用作默认值)。可以为您的自定义数据类型注册自定义“类型支持”类。 - BigCardinal和BigInteger数据类型。 - Delphi中的智能指针
该库正在积极开发中。事实上,作者在一天内修复了我发现的一个小错误。

您可以在Alex的博客上了解有关该库的更多信息,并从Google code下载DeHL。


0

我认为如果你能够进行加法,那么你就可以使用它来进行减法、乘法和除法。我应该假设溢出将被简单地忽略吗?

我似乎记得有一种使用异或运算符来添加位变量的方法。我现在正在寻找这个答案。

希望这会指引你朝着正确的方向前进。如果我能找到那个异或代码,我会为你发布的。

这里是: 按位操作 排他性异或经常用于位操作。例如: 1 xor 1 = 0 1 xor 0 = 1 1110 xor 1001 = 0111(这相当于没有进位的加法)

参考文献为: http://www.absoluteastronomy.com/topics/Exclusive_disjunction


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接