快速将整数转换为 base64 字符串并返回
将一个正的 32 位整数转换为 base64 字符串。这是将整数编码/解码为文本的最快和最短的方法。可以轻松修改为 64 位整数。
引言
我经常需要将正整数 ID 编码为文本,通过 socket 发送,并且希望消息尽可能短,编码/解码尽可能快。使用 C#,很容易将你的整数 ID 作为 base 10 或 base 16 字符串发送,但使用 base 64 或 base 62 或 base 36 或 base 32 编码的字符串可以节省大量空间。该网站上还有另一篇文章介绍 base 36 整数的编码和解码,但它使用 Math.Pow
,这非常慢。
通过选择 Base 64(由 0-9、A-Z、a-z、+、- 组成),它完美地适应 6 位,我可以非常快速地编码和解码。我还可以将九或十位数的 base 10 Int32
放入一个五字符的 base 64 字符串中。
事实上,这个应用程序表明,C# 的 Convert.ToInt32
加上 Convert.ToString
比使用我的 base 64 编码函数慢 5½ 倍!
代码非常简单,可以轻松修改为 Int64
或传递带有偏移量的 char[]
,这对于 socket 相关操作很有用。对于编码,你可以选择编码的字符数。一个字符给你 0-63,当然,两个是 4096,三个是 262,144 等。
它很容易翻译成 C 或 C++。如果你下载该应用程序,你可以看到一些演示和一个使用高性能计时器的速度测试。但除此之外,你所需的所有代码都在这里
using System;
using System.Collections.Generic;
using System.Text;
class Base64
{
static char[] b64e = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
'U', 'V', 'W', 'X', 'Y', 'Z',
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z',
'+', '/'};
static int[] b64d = new int[] { 000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,062,000,000,000,063,000,001,
002,003,004,005,006,007,008,009,000,000,
000,000,000,000,000,010,011,012,013,014,
015,016,017,018,019,020,021,022,023,024,
025,026,027,028,029,030,031,032,033,034,
035,000,000,000,000,000,000,036,037,038,
039,040,041,042,043,044,045,046,047,048,
049,050,051,052,053,054,055,056,057,058,
059,060,061,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000,000,000,000,000,
000,000,000,000,000,000};
public static string b64ConvertInt(int value, int length)
{
// length should be between 1 and 5 only
if (length == 5)
{
char[] c = new char[5];
c[0] = b64e[(value & 1056964608) >> 24];
c[1] = b64e[(value & 16515072) >> 18];
c[2] = b64e[(value & 258048) >> 12];
c[3] = b64e[(value & 4032) >> 06];
c[4] = b64e[(value & 63)];
return new string(c);
}
else if (length == 4)
{
char[] c = new char[4];
c[0] = b64e[(value & 16515072) >> 18];
c[1] = b64e[(value & 258048) >> 12];
c[2] = b64e[(value & 4032) >> 06];
c[3] = b64e[(value & 63)];
return new string(c);
}
else if (length == 3)
{
char[] c = new char[3];
c[0] = b64e[(value & 258048) >> 12];
c[1] = b64e[(value & 4032) >> 06];
c[2] = b64e[(value & 63)];
return new string(c);
}
else if (length == 2)
{
char[] c = new char[2];
c[0] = b64e[(value & 4032) >> 06];
c[1] = b64e[(value & 63)];
return new string(c);
}
else
{
return Convert.ToString(b64e[(value & 63)]);
}
}
public static int b64ConvertString(string s)
{ // string s should be between 1 and 5 character long only
int n = s.Length;
char[] c = s.ToCharArray();
if (n == 5)
{
return (b64d[c[0]] << 24) + (b64d[c[1]] << 18) +
(b64d[c[2]] << 12) + (b64d[c[3]] << 6) + b64d[c[4]];
}
else if (n == 4)
{
return (b64d[c[0]] << 18) + (b64d[c[1]] << 12) +
(b64d[c[2]] << 6) + b64d[c[3]];
}
else if (n == 3)
{
return (b64d[c[0]] << 12) + (b64d[c[1]] << 6) + b64d[c[2]];
}
else if (n == 2)
{
return (b64d[c[0]] << 6) + b64d[c[1]];
}
else if (n == 1)
{
return b64d[c[0]];
}
return 0;
}
}