【问题标题】:Read and write more than 8 bit symbols读写8位以上的符号
【发布时间】:2016-07-25 20:02:16
【问题描述】:

我正在尝试编写一个编码文件。该文件有 9 到 12 位符号。在编写文件时,我猜它没有正确写入 9 位符号,因为我无法解码该文件。虽然当文件中只有 8 位符号时。一切正常。这就是我写文件的方式

File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default);

ReadAllText 函数调用的读取也是如此。
去这里的路是什么?


我正在使用 ZXing 库使用 RS 编码器对我的文件进行编码。

 ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit
 int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c);
 enc.encode(bytesAsInts, parity);
 byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray();
 string contentWithParity = (ASCIIEncoding.Default.GetString(bytes.ToArray()));
 WriteBackContent += contentWithParity;
 File.AppendAllText(outputFileName, WriteBackContent, ASCIIEncoding.Default);

就像在代码中一样,我正在使用 AZTEC_DATA_12 初始化我的编码器,这意味着 12 位符号。因为 RS Encoder 需要 int 数组,所以我将其转换为 int 数组。并像这里一样写入文件。但它适用于 AZTEC_DATA_8 8 位符号,但不适用于 AZTEC_DATA_12。

【问题讨论】:

    标签: c# file filestream zxing symbols


    【解决方案1】:

    主要问题在这里:

    byte[] bytes = bytesAsInts.Select(x => (byte)x).ToArray();
    

    将单个整数转换为单个字节时,您基本上会丢弃部分结果。


    如果您在调用encode() 之后查看数组,您可以看到某些数组元素的值高于255,因此它们不能表示为字节。但是,在上面引用的代码中,您将整数数组中的每个元素都转换为字节,当元素的值大于 255 时更改元素。

    所以要存储encode() 的结果,您必须将整数数组转换为字节数组,以不丢失或修改值。

    为了在字节数组和整数数组之间进行这种转换,可以使用函数Buffer.BlockCopy()。如何使用这个函数的一个例子是in this answer

    使用答案中的样本和注释中的样本进行两种转换:将字节数组转换为整数数组以传递给 encode() 函数并转换从 encode() 返回的整数数组函数返回一个字节数组。

    以下是链接答案中的示例代码:

    // Convert byte array to integer array
    byte[] result = new byte[intArray.Length * sizeof(int)];
    Buffer.BlockCopy(intArray, 0, result, 0, result.Length);
    
    // Convert integer array to byte array (with bugs fixed)
    int bytesCount = byteArray.Length;
    int intsCount = bytesCount / sizeof(int);
    if (bytesCount % sizeof(int) != 0) intsCount++;
    int[] result = new int[intsCount];            
    Buffer.BlockCopy(byteArray, 0, result, 0, byteArray.Length);
    

    现在关于将数据存储到文件中:不要将数据直接通过Encoding.GetString() 转换为字符串。并非所有位序列都是任何给定字符集中字符的有效表示。因此,将随机字节的随机序列转换为字符串有时会失败。

    相反,要么通过File.WriteAllBytes() / File.ReadAllBytes() 将字节数组直接存储/读取到文件中,要么使用Convert.ToBase64()Convert.FromBase64() 处理字节数组的base64 编码字符串表示。


    这里结合了一些示例代码:

        ReedSolomonEncoder enc = new ReedSolomonEncoder(GenericGF.AZTEC_DATA_12);//if i use AZTEC_DATA_8 it works fine beacuse symbol size is 8 bit
        int[] bytesAsInts = Array.ConvertAll(toBytes.ToArray(), c => (int)c);
        enc.encode(bytesAsInts, parity);
    
        // Turn int array to byte array without loosing value
        byte[] bytes = new byte[bytesAsInts.Length * sizeof(int)];
        Buffer.BlockCopy(bytesAsInts, 0, bytes, 0, bytes.Length);
    
        // Write to file
        File.WriteAllBytes(outputFileName, bytes);
    
        // Read from file
        bytes = File.ReadAllBytes(outputFileName);            
    
        // Turn byte array to int array 
        int bytesCount = bytes.Length * 40;
        int intsCount = bytesCount / sizeof(int);
        if (bytesCount % sizeof(int) != 0) intsCount++;
        int[] dataAsInts = new int[intsCount];
        Buffer.BlockCopy(bytes, 0, dataAsInts, 0, bytes.Length);
    
        // Decoding
        ReedSolomonDecoder dec = new ReedSolomonDecoder(GenericGF.AZTEC_DATA_12);
        dec.decode(dataAsInts, parity);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-12
      • 2013-06-21
      • 2015-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-21
      • 2014-12-12
      相关资源
      最近更新 更多