Jump to content
Sign in to follow this  
Turan Can

IPV6 to number

Recommended Posts

Hi All,

 

I want to convert IPV6 to digital number. I need to make "IP2Location" IPV4 and IPV6 database query. I need help with this.

I added a working example for IPV4.

The biggest problem here is that the integer value is a certain number.
Since IPV6 is longer than numbers, even string is sufficient.

 

function GetIPNumberIPV4(ip: string): integer;
var
  List: TStringList;
  A, B, C, D, E, F: integer; //Biginteger...?
  total: string;
begin
  Result := 0;

  if ip = '::1' then
    ip := '127.0.0.1';

  List := TStringList.Create;
  try
    List.Delimiter := '.';
    List.StrictDelimiter := True;
    List.DelimitedText := ip;

    A := strtoint(List[0]);
    B := strtoint(List[1]);
    C := strtoint(List[2]);
    D := strtoint(List[3]);

 ////Result :=  (A shl 40) +  (B shl 32) + (C shl 24) + (D shl 16) + (E shl 8) + F; // BIG INTEGER PROBLEMS..

     Result := (A shl 24) + (B shl 16) + (C shl 8) + D;
  finally
    List.Free;
  end;
end;

 

 

IPV4 and IPV6 An example of a code that works correctly, but in c #, :(

 

        private void button1_Click(object sender, EventArgs e)
        {
            //string strIP = "64.233.191.255";
            string strIP = "2404:6800:4001:805::1006";
            System.Net.IPAddress address;
            System.Numerics.BigInteger ipnum;

            if (System.Net.IPAddress.TryParse(strIP, out address))
            {
                byte[] addrBytes = address.GetAddressBytes();

                if (System.BitConverter.IsLittleEndian)
                {
                    System.Collections.Generic.List<byte> byteList = new System.Collections.Generic.List<byte>(addrBytes);
                    byteList.Reverse();
                    addrBytes = byteList.ToArray();
                }

                if (addrBytes.Length > 8)
                {
                    //IPv6
                    ipnum = System.BitConverter.ToUInt64(addrBytes, 8);
                    ipnum <<= 64;
                    ipnum += System.BitConverter.ToUInt64(addrBytes, 0);
                }
                else
                {
                    //IPv4
                    ipnum = System.BitConverter.ToUInt32(addrBytes, 0);
                }
            }
        }
 

Share this post


Link to post

Is there a type that can hold a number larger than "int64"? A helper.pas or function etc.

"47875086426098177934326549022813196294" big lenght 38 or 50.

 

 

Share this post


Link to post

An IPv6 address is 128 bits. The answer is no. You'd need two UInt64s to hold that.

Share this post


Link to post

You need to put as string to compile.

 

var

b:BigInteger;

begin

b:=‘47875086426098177934326549022813196294’;

Share this post


Link to post
2 hours ago, Turan Can said:

Dear Lars,

 

Thanks for the quick response

 

I tried this, but it didn't work. He did not accept the big number.

 

....

var

b:BigInteger;

begin

b:=47875086426098177934326549022813196294; //does not run the project.

 

https://github.com/rvelthuis/DelphiBigNumbers

http://www.rvelthuis.de/programs/bigintegers.html

 

If that code would compile, then there wouldn't be much point in having the library. Think about what the literal on the rhs of the assignment actually is. 

  • Like 1

Share this post


Link to post

Never mind everything.
I didn't ask anything.

The real problem is this.
I need the code that converts IPV6 to digital number.

Share this post


Link to post
uses
  System.SysUtils, VCL.Dialogs, Velthuis.BigIntegers;

function IPV6ToNumberDigits(const AIPV6: string): string;
var
  LBigInteger: BigInteger;
begin
  BigInteger.Hex;
  LBigInteger := AIPV6.Replace(':', '', [rfReplaceAll]);
  BigInteger.Decimal;
  Result := string(LBigInteger);
end;

function NumberDigitsToIPV6(const ANumberDigits: string): string;
var
  LBigInteger: BigInteger;
  I: Integer;
begin
  LBigInteger := ANumberDigits;
  BigInteger.Hex;
  Result := string(LBigInteger).ToLower.PadLeft(32, '0');
  BigInteger.Decimal;
  for I := 0 to 6 do
    Result := Result.Insert((4 * (I+1)) + I, ':');
end;

procedure TForm1.FormCreate(Sender: TObject);
const
  IPV6_EXAMPLE = '2001:0db8:85a3:08d3:1319:8a2e:0370:7344';
begin
  showmessage('Original: ' + IPV6_EXAMPLE + #13#10 +
    'Number digits: ' + IPV6ToNumberDigits(IPV6_EXAMPLE) + #13#10 +
    'IPV6 of the number digits: ' + NumberDigitsToIPV6(IPV6ToNumberDigits(IPV6_EXAMPLE)));
end;

Result:

Original: 2001:0db8:85a3:08d3:1319:8a2e:0370:7344
Number digits: 42540766452641195744311209248773141316
IPV6 of the number digits: 2001:0db8:85a3:08d3:1319:8a2e:0370:7344

Remarks: This solution is not thread-safe.

Edited by vfbb

Share this post


Link to post

@vfbb

Why do you think this is not threadsafe, because of the

AIPV6.Replace(

or because of the use of BigInteger at all ?

 

When using local string copies of the first case, this should be OK,
or are the BigInteger intrinsically not threadsafe (never used them yet) ?

 

 

Share this post


Link to post
4 hours ago, Rollo62 said:

@vfbb

Why do you think this is not threadsafe, because of the


AIPV6.Replace(

or because of the use of BigInteger at all ?

 

When using local string copies of the first case, this should be OK,
or are the BigInteger intrinsically not threadsafe (never used them yet) ?

Because the used methods of the BigInteger changes a global variable.

BigInteger.Hex;
BigInteger.Decimal;

But I was looking, it is possible to avoid these methods, so this new example will be safe:

uses
  System.SysUtils, Velthuis.BigIntegers;

function IPV6ToNumberDigits(const AIPV6: string): string;
var
  LBigInteger: BigInteger;
begin
  if not BigInteger.TryParse(AIPV6.Replace(':', '', [rfReplaceAll]), 16, LBigInteger) then
    Exit('');
  Result := LBigInteger.ToString;
end;

function NumberDigitsToIPV6(const ANumberDigits: string): string;
var
  I: Integer;
begin
  if ANumberDigits.IsEmpty then
    Exit('');
  Result := BigInteger(ANumberDigits).ToHexString.ToLower.PadLeft(32, '0');
  for I := 0 to 6 do
    Result := Result.Insert((4 * (I+1)) + I, ':');
end;

 

  • Like 1

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×