gpt4 book ai didi

objective-c - 如何从 HEX 值计算 CRC-16?

转载 作者:搜寻专家 更新时间:2023-10-30 20:20:55 24 4
gpt4 key购买 nike

在我的代码中,我需要为存储为 NSdata 的 HEX 值计算 CRC-16 16 位值,下面是在 c 中计算 CRC-16 的代码片段。

   void UpdateCRC(unsigned short int *CRC, unsigned char x)
{
// This function uses the initial CRC value passed in the first
// argument, then modifies it using the single character passed
// as the second argument, according to a CRC-16 polynomial
// Arguments:
// CRC -- pointer to starting CRC value
// x -- new character to be processed
// Returns:
// The function does not return any values, but updates the variable
// pointed to by CRC
static int const Poly = 0xA001;
int i;
bool flag;
*CRC ^= x;
for (i=0; i<8; i++)
// CRC-16 polynomial
{
flag = ((*CRC & 1) == 1);
*CRC = (unsigned short int)(*CRC >> 1);
if (flag)
*CRC ^= Poly;
}
return;
}

保存如下十六进制值的 NSdata

const char connectByteArray[] = {
0x21,0x01,0x90,0x80,0x5F
};
NSData* data = [NSData dataWithBytes: connectByteArray length:sizeof(connectByteArray)];

最佳答案

我用下面的 C 程序解决了,我希望它能帮助别人..干杯!!!

#include <string.h>
#include <stdio.h>


const int order = 16;
const unsigned long polynom = 0x8005;
const int direct = 1;
const unsigned long crcinit = 0;
const unsigned long crcxor = 0;
const int refin = 1;
const int refout = 1;

// 'order' [1..32] is the CRC polynom order, counted without the leading '1' bit
// 'polynom' is the CRC polynom without leading '1' bit
// 'direct' [0,1] specifies the kind of algorithm: 1=direct, no augmented zero bits
// 'crcinit' is the initial CRC value belonging to that algorithm
// 'crcxor' is the final XOR value
// 'refin' [0,1] specifies if a data byte is reflected before processing (UART) or not
// 'refout' [0,1] specifies if the CRC will be reflected before XOR


// Data character string

const unsigned char string[] = {0x05,0x0f,0x01,0x00,0x00,0x99};

// internal global values:

unsigned long crcmask;
unsigned long crchighbit;
unsigned long crcinit_direct;
unsigned long crcinit_nondirect;
unsigned long crctab[256];


// subroutines

unsigned long reflect (unsigned long crc, int bitnum) {

// reflects the lower 'bitnum' bits of 'crc'

unsigned long i, j=1, crcout=0;

for (i=(unsigned long)1<<(bitnum-1); i; i>>=1) {
if (crc & i) crcout|=j;
j<<= 1;
}
return (crcout);
}



void generate_crc_table() {

// make CRC lookup table used by table algorithms

int i, j;
unsigned long bit, crc;

for (i=0; i<256; i++) {

crc=(unsigned long)i;
if (refin) crc=reflect(crc, 8);
crc<<= order-8;

for (j=0; j<8; j++) {

bit = crc & crchighbit;
crc<<= 1;
if (bit) crc^= polynom;
}

if (refin) crc = reflect(crc, order);
crc&= crcmask;
crctab[i]= crc;
}
}



unsigned long crctablefast (unsigned char* p, unsigned long len) {

// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
// only usable with polynom orders of 8, 16, 24 or 32.

unsigned long crc = crcinit_direct;

if (refin) crc = reflect(crc, order);

if (!refin) while (len--) crc = (crc << 8) ^ crctab[ ((crc >> (order-8)) & 0xff) ^ *p++];
else while (len--) crc = (crc >> 8) ^ crctab[ (crc & 0xff) ^ *p++];

if (refout^refin) crc = reflect(crc, order);
crc^= crcxor;
crc&= crcmask;

return(crc);
}



unsigned long crctable (unsigned char* p, unsigned long len) {

// normal lookup table algorithm with augmented zero bytes.
// only usable with polynom orders of 8, 16, 24 or 32.

unsigned long crc = crcinit_nondirect;

if (refin) crc = reflect(crc, order);

if (!refin) while (len--) crc = ((crc << 8) | *p++) ^ crctab[ (crc >> (order-8)) & 0xff];
else while (len--) crc = ((crc >> 8) | (*p++ << (order-8))) ^ crctab[ crc & 0xff];

if (!refin) while (++len < order/8) crc = (crc << 8) ^ crctab[ (crc >> (order-8)) & 0xff];
else while (++len < order/8) crc = (crc >> 8) ^ crctab[crc & 0xff];

if (refout^refin) crc = reflect(crc, order);
crc^= crcxor;
crc&= crcmask;

return(crc);
}



unsigned long crcbitbybit(unsigned char* p, unsigned long len) {

// bit by bit algorithm with augmented zero bytes.
// does not use lookup table, suited for polynom orders between 1...32.

unsigned long i, j, c, bit;
unsigned long crc = crcinit_nondirect;

for (i=0; i<len; i++) {

c = (unsigned long)*p++;
if (refin) c = reflect(c, 8);

for (j=0x80; j; j>>=1) {

bit = crc & crchighbit;
crc<<= 1;
if (c & j) crc|= 1;
if (bit) crc^= polynom;
}
}

for (i=0; i<order; i++) {

bit = crc & crchighbit;
crc<<= 1;
if (bit) crc^= polynom;
}

if (refout) crc=reflect(crc, order);
crc^= crcxor;
crc&= crcmask;

return(crc);
}



unsigned long crcbitbybitfast(unsigned char* p, unsigned long len) {

// fast bit by bit algorithm without augmented zero bytes.
// does not use lookup table, suited for polynom orders between 1...32.

unsigned long i, j, c, bit;
unsigned long crc = crcinit_direct;

for (i=0; i<len; i++) {

c = (unsigned long)*p++;
if (refin) c = reflect(c, 8);

for (j=0x80; j; j>>=1) {

bit = crc & crchighbit;
crc<<= 1;
if (c & j) bit^= crchighbit;
if (bit) crc^= polynom;
}
}

if (refout) crc=reflect(crc, order);
crc^= crcxor;
crc&= crcmask;

return(crc);
}



int main() {

// test program for checking four different CRC computing types that are:
// crcbit(), crcbitfast(), crctable() and crctablefast(), see above.
// parameters are at the top of this program.
// Result will be printed on the console.

int i;
unsigned long bit, crc;


// at first, compute constant bit masks for whole CRC and CRC high bit

crcmask = ((((unsigned long)1<<(order-1))-1)<<1)|1;
crchighbit = (unsigned long)1<<(order-1);


// check parameters

if (order < 1 || order > 32) {
printf("ERROR, invalid order, it must be between 1..32.\n");
return(0);
}

if (polynom != (polynom & crcmask)) {
printf("ERROR, invalid polynom.\n");
return(0);
}

if (crcinit != (crcinit & crcmask)) {
printf("ERROR, invalid crcinit.\n");
return(0);
}

if (crcxor != (crcxor & crcmask)) {
printf("ERROR, invalid crcxor.\n");
return(0);
}


// generate lookup table

generate_crc_table();


// compute missing initial CRC value

if (!direct) {

crcinit_nondirect = crcinit;
crc = crcinit;
for (i=0; i<order; i++) {

bit = crc & crchighbit;
crc<<= 1;
if (bit) crc^= polynom;
}
crc&= crcmask;
crcinit_direct = crc;
}

else {

crcinit_direct = crcinit;
crc = crcinit;
for (i=0; i<order; i++) {

bit = crc & 1;
if (bit) crc^= polynom;
crc >>= 1;
if (bit) crc|= crchighbit;
}
crcinit_nondirect = crc;
}


// call CRC algorithms using the CRC parameters above and print result to the console

printf("\n");
printf("CRC tester v1.1 written on 13/01/2003 by Sven Reifegerste (zorc/reflex)\n");
printf("-----------------------------------------------------------------------\n");
printf("\n");
printf("Parameters:\n");
printf("\n");
printf(" polynom : 0x%x\n", polynom);
printf(" order : %d\n", order);
printf(" crcinit : 0x%x direct, 0x%x nondirect\n", crcinit_direct, crcinit_nondirect);
printf(" crcxor : 0x%x\n", crcxor);
printf(" refin : %d\n", refin);
printf(" refout : %d\n", refout);
printf("\n");
printf(" data string : '%s' (%d bytes)\n", string, strlen(string));
printf("\n");
printf("Results:\n");
printf("\n");

printf(" crc bit by bit : 0x%x\n", crcbitbybit((unsigned char *)string, 6));
printf(" crc bit by bit fast : 0x%x\n", crcbitbybitfast((unsigned char *)string, strlen(string)));
if (!(order&7)) printf(" crc table : 0x%x\n", crctable((unsigned char *)string, strlen(string)));
if (!(order&7)) printf(" crc table fast : 0x%x\n", crctablefast((unsigned char *)string, strlen(string)));

return(0);
}

关于objective-c - 如何从 HEX 值计算 CRC-16?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11481782/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com