2009-03-30 2 views
4

Я работаю с IPv6-адреса в виде:Арифметика с адресами IPv6 (большие числа)

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

Внутренне, я храню их в массиве:

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

Мне нужно манипулировать IPv6-адрес в ряде способов, включая добавление, деление, умножение и т.д. Может кто-нибудь предложить хороший способ сделать это?

Я предполагаю, что я должен отметить, что я работаю с Delphi 2009

+0

Почему бы вам не сохранить их внутренне как 2D-массив? 8x2 байт, как и адрес IPv4, будут обрабатываться как 4x1 байт. –

+0

Я использую тот же тип, который используется в Synapse, поэтому я могу использовать несколько функций, которые он уже предоставляет. Не уверен, почему они не хранят его как 8x2, но так оно и есть :) – norgepaul

ответ

3

После того, как вы попробовали много предложений, я не смог найти библиотеку, которая отвечала всем моим потребностям и была без ошибок. Я искал немного сложнее и нашел относительно новую библиотеку Alex Ciobanu, которая делает BigIntegers (и Big Cardinals) без проблем, позволяя вам манипулировать ими во многом так же, как вы управляете нормальными целыми, кардиналами и т. Д.

Как и BigIntegers , библиотека также предоставляет ряд очень полезных функций. Из ридми:

  • Набор родовых коллекций классов (список, словарь, HashSet и т.д.).
  • Дата функциональность/Время (эквивалент DateTime .NET в структурах как-то )
  • Типа концепции поддержки, которая определяет набора по умолчанию «поддержка классов» для всех объединенных в нескольких структурах каждого встроенные типов Delphi (используется как значения по умолчанию в коллекциях). Пользовательский «Тип поддержки» может быть зарегистрирован для ваших пользовательских данных .
  • Типы данных BigCardinal и BigInteger.
  • Интеллектуальные указатели в Delphi

Библиотека активно развивается. Фактически, автор зафиксировал небольшую ошибку, которую я обнаружил в течение дня.

Подробнее об библиотеке можно узнать на блоге Alex's и скачать DeHL от Google code.

0

Я бы сказал, что если вы можете добавить, вы можете использовать его для вычитания, умножения и деления с использованием сложения. Должен ли я предположить, что переполнение будет просто проигнорировано?

Кажется, что я напоминаю метод добавления бит-ориентированных переменных с помощью XOR. Я ищу этот ответ сейчас.

Надеюсь, это укажет вам в правильном направлении. Если я найду этот код XOR, я отправлю его вам.

Здесь находится: Побитовая операция Эксклюзивная дизъюнкция часто используется для побитовых операций. Примеры: 1 XOR 1 = 0 1 XOR 0 = 1 1110 исключающее 1001 = 0111 (это эквивалентно добавлению без переноса)

А ссылка: http://www.absoluteastronomy.com/topics/Exclusive_disjunction

4

Джес Клинке написал блок bignum для Pascal here.

Отказ от ответственности: Я не использовал эту библиотеку лично.

+0

Wow ... обрабатывает Int128, Int256 ... вплоть до Int3k плюс несколько на всякий случай. :) Приятная находка, похоже, что она решит проблему хорошо, хотя я еще не вырыл слишком глубоко в куски. (+1 желаю, чтобы я мог дать больше) – skamradt

+0

Я попытался использовать эту библиотеку, но у нее есть основная ошибка в функции вычитания. Я попытался связаться с автором, но не получил ответа. См. Мой собственный ответ на этот вопрос для другого варианта. – norgepaul

3

Я как-то написал IPv4 and IPv6 conversion unit, включая тип пользовательского варианта для обоих типов IP-адресов.

Например, с этими типами Variant, следующие примеры арифметика и преобразования возможны:

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

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; 

Пользовательские типы вариант действительно довольно мощный.

+0

Я загрузил ваш блок преобразования IPv4 и IPv6, и прежде всего, я должен поздравить вас с вашей работой, это отлично. Теперь то, что действительно отсутствует в вашем блоке, - это функция, чтобы проверить, не является ли определенный IPv6-адрес вне области подсети IPv6. Что-то вроде IsInIPv6Subnet ('2001: db8: 4000: 0123: ac45 :: 01ff', '2001: db8: 4000 ::/36'); Любые планы по добавлению таких функций? – FjodrSo

Смежные вопросы