Turan Can 3 Posted April 8, 2020 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
Turan Can 3 Posted April 8, 2020 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
Lars Fosdal 1792 Posted April 8, 2020 An IPv6 address is 128 bits. The answer is no. You'd need two UInt64s to hold that. Share this post Link to post
Lars Fosdal 1792 Posted April 8, 2020 That said, there is BigInteger from https://github.com/rvelthuis/DelphiBigNumbers Share this post Link to post
Turan Can 3 Posted April 8, 2020 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 Share this post Link to post
vfbb 285 Posted April 8, 2020 You need to put as string to compile. var b:BigInteger; begin b:=‘47875086426098177934326549022813196294’; Share this post Link to post
David Heffernan 2345 Posted April 8, 2020 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. 1 Share this post Link to post
Turan Can 3 Posted April 8, 2020 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
vfbb 285 Posted April 8, 2020 (edited) 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 April 9, 2020 by vfbb Share this post Link to post
Rollo62 536 Posted April 9, 2020 @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
vfbb 285 Posted April 9, 2020 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; 1 Share this post Link to post
limelect 48 Posted April 9, 2020 If you have no solution yet I have it on Freelancer. Share this post Link to post
Turan Can 3 Posted April 17, 2020 Thank you very much for your support. I did this, but bigint didn't work for me. I'll check again. Share this post Link to post