Is it possible encode IPV4 into 6 or less ASCII Printable Characters to create an ultra portable ID that users can tell to each other, which really represents an IP.
-
You can't compress such small data. But you can represent it in another base, per example base16, hexadecimal, an IP would be like C0A80A01 – Gusman Mar 18 '18 at 23:54
-
1There are 95 printable characters. With 6 of them, there are about 7.3e11 possible combinations. There are only about 4.3e9 IPv4 addresses, so yes it is possible. – Dave M Mar 19 '18 at 00:01
-
You could theoretically get away with only 5 printable characters, there would be about 7 billion combinations (you only need 4.3 billion) – Dave M Mar 19 '18 at 00:04
-
@DaveM You could even reduce it to 85 different characters to express all 4.3 billion combinations with just 5 character positions (as 85^5 = 4.4 billion different combinations). – ckuri Mar 19 '18 at 00:30
-
isnt it obvious im just using compress as a way to get my idea across? I explain in the body – DOSLuke Mar 19 '18 at 00:31
3 Answers
You could try this base95
implementation it will get it down to 5 printable characters
public static class Base95Extension
{
private const string PrintableChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !?\"'`^#$%@&*+=/.,:;|\\_<>[]{}()~-";
private const int Length = 95;
public static uint ToUInt32(this IPAddress ip)
{
return BitConverter.ToUInt32(ip.GetAddressBytes(), 0);
}
public static IPAddress ToIpAddress(this uint source)
{
return new IPAddress(BitConverter.GetBytes(source));
}
public static string ToBase95(this IPAddress ip)
{
var num = ip.ToUInt32();
var result = string.Empty;
uint index = 0;
while (num >= Math.Pow(Length, index))
{
index++;
}
while (index-- > 0)
{
var pow = (uint)Math.Pow(Length, index);
var div = num / pow;
result += PrintableChars[(int)div];
num -= pow * div;
}
return result;
}
public static IPAddress ToIpAddress(this string s)
{
uint result = 0;
var chars = s.Reverse()
.ToArray();
for (var i = 0; i < chars.Length; i++)
{
var pow = Math.Pow(Length, i);
var ind = PrintableChars.IndexOf(chars[i]);
result += (uint)(pow * ind);
}
return new IPAddress(BitConverter.GetBytes(result));
}
}
Usage
var ip = "255.255.255.255";
var ipAddress = IPAddress.Parse(ip);
var result = ipAddress.ToBase95();
Console.WriteLine(ip);
Console.WriteLine(result);
Console.WriteLine(result.ToIpAddress());
Output
255.255.255.255
Q#F 5
255.255.255.255
[Demo Here][1]

- 79,002
- 9
- 103
- 141
-
You can easily get 6 digits if you use at least 41 different characters as this allows for 41^6=4.7 billion different combinations which is sufficient to cover all 2^32=4.3 billion possible IP addresses. – ckuri Mar 19 '18 at 00:08
-
Base64 would be only 6 characters, but this is easier to read and harder to mistype since it uses only the characters 0-9, A-F. – Dave S Mar 19 '18 at 00:09
-
Thanks. Ive done the same thing with some similar, if not easier to read code. Ill post when i get home. – DOSLuke Mar 19 '18 at 00:34
-
Also you can get rid of the == at the end as its just padding. You can add it later easily. – DOSLuke Mar 19 '18 at 00:35
You can either try:
uint iaddress = BitConverter.ToUInt32(IPAddress.Parse(address).GetAddressBytes(), 0);
or use the structure here
or use the formula:
a.b.c.d => a*2^24 + b*2^16 + c*2^8 + d (which I think is faster)
-
I actually used that im my solution to the problem. After getting the int, i turn it into a byte array and then into base 64 – DOSLuke Mar 19 '18 at 00:39
So I have figured something out. it accomplishes the same thing as Michael Randall's answer, in essence. His is probably more efficient, and uses less dependencies. this is just what I came up with. the main upside I see with mine is less special chars are included in the encoded string, so its easy for people to verbally communicate.
public static string Base64EncodeIP(string ip)
{
UInt32 ipasint = BitConverter.ToUInt32(IPAddress.Parse(ip).GetAddressBytes(), 0);
byte[] ipasbytes = BitConverter.GetBytes(ipasint);
string encodedip = Convert.ToBase64String(ipasbytes);
return encodedip.Replace("=", "");
}
public static string Base64DecodeIP(string encodedIP)
{
//re-add however much padding is needed, to make the length a multiple of 4
if (encodedIP.Length % 4 != 0)
encodedIP += new string('=', 4 - encodedIP.Length % 4);
byte[] ipasbytes = Convert.FromBase64String(encodedIP);
UInt32 ipasint = BitConverter.ToUInt32(ipasbytes, 0);
return new IPAddress(BitConverter.GetBytes(ipasint)).ToString();
}
EDIT
Links for some code I used:
How to convert an IPv4 address into a integer in C#?
Remove trailing "=" when base64 encoding

- 63
- 1
- 10
-
side note, if anyone wants to do a speed comparison, plz post the results :) – DOSLuke Mar 19 '18 at 03:35
-
you are trying to decode it twice. typo? i think line 36 should use the encode function? it runs perfectly after changing it to the encode function. – DOSLuke Mar 20 '18 at 02:30