7

我目前正在尝试让 schifra 库运行以进行一些测试,以便稍后在我的代码中实现它。

我目前正在查看 schifra_reed_solomon_example02.cpp 并尝试了解如何设置值以满足我的需求。

/* Finite Field Parameters */
   const std::size_t field_descriptor                 =   8; // GF(2^8) ok
   const std::size_t generator_polynommial_index      = 120; // what is this?
   const std::size_t generator_polynommial_root_count =  32; // polynomial up to x^32

   /* Reed Solomon Code Parameters */
   const std::size_t code_length = 255;  // amount of symbols in codeword
   const std::size_t fec_length  = 32;  // minimal distance d ?
   const std::size_t data_length = code_length - fec_length; // amount of symbols my message has

所以我想要的是 n, k , d = (128, 16, 113) 的 RS-Code

我将进行以下操作:

/* Finite Field Parameters */
   const std::size_t field_descriptor                 =   8; // I want GF(2^8)
   const std::size_t generator_polynommial_index      = 120; // still not knowing
   const std::size_t generator_polynommial_root_count =  16; // because polynomial up to 16

   /* Reed Solomon Code Parameters */
   const std::size_t code_length = 128;  // 128 byte codewords
   const std::size_t fec_length  = 113;  // minimal distance, 113 because d = n - k +1
   const std::size_t data_length = 16; 

然后我在编码消息时收到一个错误。

schifra::galois::field_polynomial generator_polynomial(field);

   schifra::sequential_root_generator_polynomial_creator(field,
                                                         generator_polynommial_index,
                                                         generator_polynommial_root_count,
                                                         generator_polynomial);

   /* Instantiate Encoder and Decoder (Codec) */
   schifra::reed_solomon::encoder<code_length,fec_length> encoder(field,generator_polynomial);
   schifra::reed_solomon::decoder<code_length,fec_length> decoder(field,generator_polynommial_index);

   std::string message = "A professional i"; // its 16 bytes
   std::cout << "Original Message:   [" << message << "]" << std::endl;
  message = message + std::string(data_length - message.length(),static_cast<unsigned char>(0x00)); // this one is also done in example

   std::cout << "Original Message:   [" << message << "]" << std::endl;
   std::cout << "Message length: " << message.length() << std::endl; // still 16 bytes

   /* Instantiate RS Block For Codec */
   schifra::reed_solomon::block<code_length,fec_length> block;

   /* Transform message into Reed-Solomon encoded codeword */
   if (!encoder.encode(message,block))
   {
      std::cout << "Error - Critical encoding failure!" << std::endl;
      return 1;
   }

然后Error - Critical encoding failure!给出。

我认为我做错的是设置多项式正确 - 也许有人可以帮助我?

4

2 回答 2

2

我是一个尝试使用 Schifra 库的初学者。我对 Reed Solomon 代码一无所知,经过数周的源代码挖掘后,我发现了一个始终有效的组合。我仍然不知道 RS 代码使用的任何数学运算。

一些可能有用的行话:

  • 符号:RS码能识别的最小信息量(一般设置为8位(1字节))
  • FEC:它是附加在数据末尾的冗余或纠错“符号”
  • 数据:您要为其生成 RS 代码的数据。
  • 伽罗瓦域:Reed Solomon 代码用于纠错的多项式或映射(我不知道 RS 代码背后的任何数学)

在不深入研究数学的情况下,有效的组合并从初始化变量中获得一些意义:

  • 字段描述符=一个符号的大小(一般设置为8位长度)
  • 生成多项式索引 = 不知道这是什么,但将其设置为 0 始终有效,并且与其他值相比,性能提升很小。
  • 生成多项式根数= 需要等于 FEC 长度
  • 代码长度= 此值必须为 (2^(符号大小或字段描述符)-1)。它表示最终编码字符串的符号数(数据符号+错误校正符号)。请注意,以位为单位的编码字符串的总大小等于代码长度*符号大小。
  • FEC 长度:纠错符号的数量。
  • 数据长度:数据符号的数量。(如 Code_length - FEC_length 示例中所启动的那样)不应触及此内容。

应该注意的是,对于特定的符号大小,代码长度是固定的,并且可以改变该代码长度的百分之几是数据以及什么是纠错符号。正如常识所暗示的,更多的纠错符号会导致更多的纠错能力。

在运行编码器时,您将块对象与数据一起作为参数传递。

在运行方法 encoder.encode 时,“块”会填充编码数据(数据 + ECC)。

损坏后,解码完成。这个链接解释了解码器可以纠正的错误和擦除的数量

解码器将块和擦除列表(如果适用)作为参数,如果擦除和错误的数量在 ECC 的范围内(查看链接),则返回原始消息/数据。

于 2019-12-01T09:33:59.937 回答
-2

Reed-Solomon 编码并不意味着与
您的参数一起工作,独立于程序代码。

您可以选择以下内容:

  • A B,即一个数据单元有多少位(例如,对于普通字节数据,B=8)。
  • A Twith 0 <= T < (2^b)/3:T 越大,纠错效果越好,但编码速度越慢。
  • 一些不可约多项式和基幂,这里不重要。

您不能选择:

  • GF/多项式基数是2^B,仅此而已。
  • 每个明文块(没有 RS 校验和数据)必须是
    (2^B - 2*T - 1)数据单元(这里是字节),仅此而已。
  • 对于每个明文块,RS 将额外计算2*T数据单元校验和数据。
  • 因此,具有明文和校验和数据的块具有2^B -1数据单元。
    这意味着,以字节为数据单元,这样的块正好有 255 个字节,仅此而已。
  • 再次解码时,最多T可以纠正错误
    的数据单元(错误可能是明文和/或校验和部分,没关系)
  • 最多2*T可以识别错误的数据单元,但必须纠正。
  • 除了2*T错误之外,所有的赌注都被取消了。

在示例代码中(部分):

const std::size_t field_descriptor = 8;
const std::size_t code_length = 255; 
const std::size_t fec_length = 32;
const std::size_t data_length = code_length - fec_length;  
  • field_descriptor 是 B。
  • code_length 是完整的块长度(明文 + 校验和)。
  • fec_length 是校验和长度。
  • data_length 是明文块长度。

因此对于每个 233 个明文字节,RS 计算 32 个校验和字节
(=255 个总字节),以便以后能够纠正多达 16 个错误字节。

在您的代码中,您选择 GF(2^8) 和字节数据,因此 B=8,因此 code_length 128 是错误的。它必须是255。校验和部分长度113太多而不是均匀,明文长度不是之前值的差异。
...

除此之外,在我在互联网上知道的 6 个 RS 代码中,Shifra 是迄今为止最差的(尽管被称赞为“高度优化”、古怪的代码、有问题的许可证,但速度非常慢……)。选择任何东西,但不要选择 Schifra。

我会检查我是否可以分享我写的东西......包括学习算法的内部工作原理,写所有东西(编码器+解码器)甚至不需要一天,它比测试机器上的Schifra快3倍然后(没有 asm,只有 C++)。缺点是只能使用基于字节的数据,即。B=8,而无法选择其他碱基。但可能无论如何你都不需要那个。

于 2015-11-10T11:44:35.107 回答