C# 将IPv4地址编码为6个或更少的ASCII可打印字符

C# 将IPv4地址编码为6个或更少的ASCII可打印字符,c#,C#,是否可以将IPV4编码为6个或更少的ASCII可打印字符,以创建一个用户可以相互告知的超便携ID,它实际上代表一个IP。您可以尝试此base95实现,它将最多可打印5个字符 public static class Base95Extension { private const string PrintableChars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ !?\"'`^#$%@&*+=/

是否可以将IPV4编码为6个或更少的ASCII可打印字符,以创建一个用户可以相互告知的超便携ID,它实际上代表一个IP。

您可以尝试此
base95
实现,它将最多可打印5个字符

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));
   }

}
输出

255.255.255.255
Q#F 5
255.255.255.255

[此处演示][1]

您可以尝试此
base95
实现,它将减少到5个可打印字符

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));
   }

}
输出

255.255.255.255
Q#F 5
255.255.255.255
[此处演示][1]

您可以尝试:

uint iaddress=BitConverter.ToUInt32(IPAddress.Parse(address.GetAddressBytes(),0)

或者使用该结构

或者使用以下公式:

a、 b.c.d=>a*2^24+b*2^16+c*2^8+d(我认为更快)

您可以尝试:

uint iaddress=BitConverter.ToUInt32(IPAddress.Parse(address.GetAddressBytes(),0)

或者使用该结构

或者使用以下公式:

a、 b.c.d=>a*2^24+b*2^16+c*2^8+d(我认为更快)


所以我想出了一些办法。从本质上讲,这与迈克尔·兰德尔的回答是一样的。His可能更高效,并且使用更少的依赖项。这正是我想到的。我所看到的主要优点是编码字符串中包含的特殊字符较少,因此人们很容易进行口头交流

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();
}
编辑 我使用的一些代码的链接:


所以我想出了一些办法。从本质上讲,这与迈克尔·兰德尔的回答是一样的。His可能更高效,并且使用更少的依赖项。这正是我想到的。我所看到的主要优点是编码字符串中包含的特殊字符较少,因此人们很容易进行口头交流

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();
}
编辑 我使用的一些代码的链接:



你不能压缩这么小的数据。但您可以用另一个基数来表示它,例如base16,十六进制,一个IP就像C0A80A01,这里有95个可打印字符。其中有6种,大约有7.3e11种可能的组合。只有大约4.3e9 IPv4地址,所以是的,这是可能的。从理论上讲,你只需要5个可打印字符,大约有70亿个组合(你只需要43亿个)@DaveM你甚至可以将其减少到85个不同的字符,用5个字符的位置来表示所有43亿个组合(85^5=44亿个不同的组合).很明显,我只是用压缩来表达我的想法。我在正文中解释说,你不能压缩这么小的数据。但是你可以用另一个基数来表示它,例如base16,十六进制,IP就像C0A80A01。有95个可打印字符。其中6个,大约有7.3e11个可能的组合。只有大约4.3e9 IPv4地址,所以是的,这是可能的。从理论上讲,你只需要5个可打印字符,大约有70亿个组合(你只需要43亿个)@DaveM你甚至可以将其减少到85个不同的字符,用5个字符的位置来表示所有43亿个组合(85^5=44亿个不同的组合).很明显,我只是用压缩来表达我的想法吗?我在正文中解释说,如果你使用至少41个不同的字符,你可以很容易地得到6个数字,因为这允许41^6=47亿个不同的组合,足以覆盖所有2^32=43亿个可能的IP地址。Base64只有6个字符,但这更简单因为它只使用字符0-9,A-F。谢谢。我用一些类似的代码做了同样的事情,如果不容易阅读的话。我回家后会发布。你也可以去掉结尾处的==作为填充。你以后可以很容易地添加它。如果你使用至少41个不同的字符,你可以很容易地得到6位数字允许41^6=47亿个不同的组合,足以覆盖所有2^32=43亿个可能的IP地址。Base64将只有6个字符,但这更容易阅读,也更难打字错误,因为它只使用字符0-9,A-F。谢谢。我对一些类似的代码做了同样的事情,如果不容易阅读的话。我收到后会发布home。你也可以去掉结尾处的==作为填充。你以后可以很容易地添加它。我实际上是用它来解决问题的。在得到int之后,我把它变成字节数组,然后变成base 64。我实际上是用它来解决问题的。在得到int之后,我把它变成字节数组,然后变成base 64请注意,如果有人想进行速度比较,请发布结果:)您正在尝试解码两次。输入错误?我认为第36行应该使用编码功能?它在更改为编码功能后运行良好。另请注意,如果有人想进行速度比较,请发布结果:)您正在尝试解码两次。打字错误我认为第36行应该使用编码功能?将其更改为encode函数后,它可以完美地运行。