本帖最后由 hotpower 于 2023-9-19 15:55 编辑
//CRCn可逆函数正运算
void CRCnVal(uint8_t* input, int n, const uint8_t* poly, const uint8_t* init, const uint8_t* xorout)
{//大端,[0]最高,[255]最低
int len = n / 8;//n为位数,len为字节数
uint8_t ch;
int i, k;
for (i = 0; i < len; i++)
{
input[i] ^= init[i];//异或初值
}
if ((poly[len - 1] & 1) != 0)
{ //最低位为1,左移CRC
for (i = 0; i < n; i++)
{//CRCn位数
ch = input[0] & 0x80;//**最高位
//左移1位
for (k = 0; k < len; k++)
{//CRCn字节数
uint8_t ch0;
if (k == len - 1) ch0 = 0;
else ch0 = (input[k + 1] & 0x80) > 0 ? 1 : 0;
input[k] <<= 1;//左移一位
input[k] |= ch0;//头尾移动
input[k] &= 0xff;
}
//多项式
if (ch != 0)
{//需要异或
for (k = 0; k < len; k++)
{//CRCn字节数
input[k] ^= poly[k];//全部异或
}
}
}
}
else
{ //右移
for (i = 0; i < n; i++)
{//CRCn位数
ch = input[len - 1] & 0x01;//**最低位
//右移1位
for (k = len - 1; k >= 0; k--)
{//CRCn字节数
uint8_t ch0;
if (k == 0) ch0 = 0;
else ch0 = (input[k - 1] & 0x01) > 0 ? 0x80 : 0;
input[k] >>= 1;//右移一位
input[k] |= ch0;//头尾移动
}
if (ch != 0)
{//需要异或
for (k = 0; k < len; k++)
{
if (k == 0) input[k] ^= poly[k] | 0x80;//强行可逆全部异或多项式
else input[k] ^= poly[k];//全部异或多项式
}
}
}
}
if (((poly[0] & 0x80) == 0) && ((poly[len - 1] & 0x01) == 0))
{ //64个不可逆权值
input[0] ^= poly[0] ^ 0x80; //取反得到64个可逆权值
input[len - 1] ^= poly[len - 1] ^ 0x01; //取反得到64个可逆权值
}
for (i = 0; i < len; i++)
{
input[i] ^= xorout[i];//异或出值
}
//return input;//输出密文
}
//CRCn可逆函数逆运算
void CRCnValx(uint8_t* output, int n, const uint8_t* poly, const uint8_t* init, const uint8_t* xorout)
{
int len = n / 8;//n为位数,len为字节数
int i, k;
for (i = 0; i < len; i++)
{
output[i] ^= xorout[i];//异或出值
}
if (((poly[0] & 0x80) == 0) && ((poly[len - 1] & 0x01) == 0))
{ //64个不可逆权值
output[0] ^= poly[0] ^ 0x80; //取反得到64个可逆权值
output[len - 1] ^= poly[len - 1] ^ 0x01; //取反得到64个可逆权值
}
if ((poly[len - 1] & 1) != 0)
{ //左移
for (i = 0; i < n; i++)
{
uint8_t ch = output[len - 1] & 0x01;//**最低位
if (ch != 0)
{
for (k = 0; k < len; k++)
{
output[k] ^= poly[k];//全部异或
}
//右移1位
for (k = len - 1; k >= 0; k--)
{
uint8_t ch0;
if (k == 0) ch0 = 0;
else ch0 = (output[k - 1] & 0x01) > 0 ? 0x80 : 0;
output[k] >>= 1;//左移逆运算需要右移一位
output[k] |= ch0;
}
output[0] |= 0x80;//最高位还原
}
else
{
//右移1位
for (int k = len - 1; k >= 0; k--)
{
uint8_t ch0;
if (k == 0) ch0 = 0;
else ch0 = (output[k - 1] & 0x01) > 0 ? 0x80 : 0;
output[k] >>= 1;//左移逆运算需要右移一位
output[k] |= ch0;
}
}
}
}
else
{ //右移
for (i = 0; i < n; i++)
{
uint8_t ch = output[0] & 0x80;//**最高位
if (ch != 0)
{
for (k = 0; k < len; k++)
{
output[k] ^= poly[k];//全部异或
}
//左移1位
for (k = 0; k < len; k++)
{
uint8_t ch0;
if (k == len - 1) ch0 = 0;
else ch0 = (output[k + 1] & 0x80) > 0 ? 1 : 0;
output[k] <<= 1;//右移逆运算需要左移一位
output[k] |= ch0;
output[k] &= 0xff;
}
output[len - 1] |= 0x01;//最低位还原
}
else
{
//左移1位
for (k = 0; k < len; k++)
{
uint8_t ch0;
if (k == len - 1) ch0 = 0;
else ch0 = (output[k + 1] & 0x80) > 0 ? 1 : 0;
output[k] <<= 1;//右移逆运算需要左移一位
output[k] |= ch0;
output[k] &= 0xff;
}
}
}
}
for (i = 0; i < len; i++)
{
output[i] ^= init[i];//异或初值
}
//return output;//输出明文
}
|