1

I would like to encode some information in Code128 barcodes which allow 96 different characters to be used in one slot. Therefore, 95 decimal would translate to 101 1111b and 96 to 1 000 0000b.

Now I need an algorithm that converts a decimal (or binary) number into 7 bit words with 96 states at maximum. I sat here all morning trying to figure that algorithm out (playing with bit shifts and logarithms), but it seems that I'm missing some important point here.

How would I translate, for example, 537 (10 0001 1001b) into such words?

4

2 回答 2

1

在玩了一些数字之后,我终于找到了解决方案。对于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);
于 2013-04-23T12:25:40.377 回答
1

将任意二进制数据编码为具有大约 96 个不同字母的字母序列通常称为二进制到文本编码或 ASCII 装甲

当您的“二进制”输入字节流是“短”并且可能具有 256 个可能字节中的任何一个,但主要是 ASCII 文本(字母、数字)时,让字母和数字代表自己是最紧凑的(1 个输入字节到 1输出字母),为超出该范围的字节保留一个或四个“转义”符号(将 1 个“异常字节”扩展为 3 或 2 个输出字母),如百分比编码带引号的可打印编码。

当您的二进制输入字节流对于所有 256 个可能的字节具有或多或少相等的频率(即,流已被加密或压缩或两者兼而有之)时,使用某种基本转换算法(例如十六进制(扩展每个八位字节为 2 个十六进制数字)或base32(将 5 个八位字节扩展为 8 个 base32 数字)或base64url(将 3 个八位字节扩展为 4 个 base64 数字)或Z85(将 4 个八位字节扩展为 5 个 base85 数字)或baseE91base95

当您的二进制输入字节流具有不相等的频率(例如主要包含 ASCII 文本)或重复,并且“足够长”时,首先压缩它是最紧凑的(可能使用LZ4LZO或 DEFLATE 或LZRW1-A),创建一个大致相等频率的压缩字节流,然后如上所述对该字节流进行编码。

于 2019-08-04T15:00:36.257 回答