我想在Code128条形码中编码一些信息,这些信息允许在一个插槽中使用96个不同的字符。因此,95
十进制将转换为101 1111b
和96
转换为1 000 0000b
。
现在我需要一种算法,将十进制(或二进制)数转换为最多96个状态的7位字。我整个上午都坐在这里试图计算出算法(使用位移和对数),但似乎我在这里缺少一些重要的观点。
我如何将537
(10 0001 1001b
)翻译成这样的字词?
答案 0 :(得分:0)
在玩了一些数字之后我终于找到了解决方案。对于883.736
:
883.736 / 96 = 9.205 R: 56
9.205 / 96 = 95 R: 85
95 / 96 = 0 R: 95
这些数字可以转换为7位字。要获得原始值:
883.736 = 56 * 96^0 + 85 * 96^1 + 95 * 96^2
用C#表示的算法(小端):
public static class Base96
{
private const int BASE = 96;
public static byte[] Encode(int number)
{
var list = new List<Byte>();
do
{
list.Add((byte)(number % BASE));
}
while ((number = (number / BASE)) > 0);
return list.ToArray();
}
public static int Decode(byte[] words)
{
int result = 0;
for (int i = 0; i < words.Length; i++)
{
result += (words[i] * (int)Math.Pow(BASE, i));
}
return result;
}
}
这样打电话:
var encoded = Base96.Encode(883736);
var decoded = Base96.Decode(encoded);
答案 1 :(得分:0)
将任意二进制数据编码成具有大约96个不同字母的字母的序列通常称为binary-to-text encoding or ASCII armor。
当您的“二进制”输入字节流为“短”并且可能具有256个可能的字节中的任何一个,但主要是ASCII文本(字母,数字)时,最紧凑的方式是让字母和数字代表自己(1个输入字节到1个输出字母),保留一个或四个“转义”符号以表示超出该范围的字节(将1个“不正常的字节”扩展为3个或2个输出字母),如percent-encoding或quoted-printable编码。
当您的二进制输入字节流在所有256个可能的字节中具有几乎相等的频率时(即,该流已被加密或压缩,或两者都被加密),使用诸如此类的base-conversion algorithm最紧凑十六进制(将每个八位位组扩展为2个十六进制数字)或base32(将5个八位位组扩展为8个base32位数字)或base64url(将3个八位组扩展为4个base64位数字)或Z85(扩展4个八位字节,以5个base85位数为单位)或baseE91或base95。
当您的二进制输入字节流具有不相等的频率(例如,主要包含ASCII文本)或重复频率并且“足够长”时,最紧凑的方式是首先对其进行压缩(也许使用LZ4或{{3} }或DEFLATE或LZO),创建一个频率大致相等的压缩字节流,然后按上述方式对该字节流进行编码。