Problems with Checksum Calculation
-
I've been trying to replicate a 1-wire 8-bit CRC checksum in Qt, but I've been having a lot of trouble. You can see an example of what I'm trying to do in Python code here: https://forum.sparkfun.com/viewtopic.php?p=51145. It uses the maxim specified polynomial of x^8 + x^5 + x^4 + 1 to compute the CRC checksum.
I have a feeling it is related to differences with Qt's QString versus the Python variables, maybe an endian issue? I've tried about 100 different combinations, but I'm really struggling to get the correct answer from any of my implementations. My latest attempt it attached for reference:
@quint8 calculateCRC(QByteArray payload)
{
// CRC table from http://forum.sparkfun.com/viewtopic.php?p=51145
const quint8 crcTable[] = {
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};// convert format QList data; for (int i = 0; i < payload.size(); i++) { data.append((quint8)payload[i]); } // calculate checksum quint8 val = 0, tmp; for (int i = 0; i < data.size(); i++) { tmp = val ^ data[i]; val = crcTable[tmp]; } return val;
}@
Using this code, I am still getting incorrect results. I have also tried switching the endian encoding (i.e. qFromBigEndian) as well as reversing the data based on some other hints I was able to find. I'm still hitting a dead end though since I can't get the correct result for a simple test case. You can check the results using this online calculator: http://www.datastat.com/sysadminjournal/maximcrc.cgi
For example, entering 00 28 00 (for 0x00 0x28 0x00) should result in 0xB7.
Does anyone have any ideas what I might be doing wrong?
-
Hi and welcome to devnet,
Just to be sure, does your function expect hexadecimal data ?
-
Thanks for the quick reply!
I have tried several different data types, but I believe the code operates using uint8's like it is coded to do right now. I've seen other implementations using unsigned chars, but that's basically the same thing.
I'm not getting the right results though, so I'm up for suggestions if you think there's a different data type I should be using for these operations.
-
Try with QByteArray::toHex(), it will give you the hexadecimal equivalent of your byte array content
-
I tried using toHex() and it does reformat the QByteArray with the correct hex formatting, but there is still something incorrect going on with the CRC operations. I found another very useful link here:
"http://fabionotes.blogspot.com/2012/07/8-bit-dallas-maxim-crc.html":http://fabionotes.blogspot.com/2012/07/8-bit-dallas-maxim-crc.htmlIt has a few other examples of 8-bit Maxim CRC algorithms. I also tried several of those ported into Qt and am still getting incorrect results with all of them. I have a feeling this might be related to LSB/MSB positioning or maybe to an encoding problem of the original data. I'm fairly new with Qt though so I'm struggling to figure out where the problem is coming from...
-
The QList without a type looks fishy to me (and useless, too).
Try this:
@
quint8 calculateCRC(QByteArray payload)
{
// CRC table from http://forum.sparkfun.com/viewtopic.php?p=51145
const quint8 crcTable[] = {
0, 94, 188, 226, 97, 63, 221, 131, 194, 156, 126, 32, 163, 253, 31, 65,
157, 195, 33, 127, 252, 162, 64, 30, 95, 1, 227, 189, 62, 96, 130, 220,
35, 125, 159, 193, 66, 28, 254, 160, 225, 191, 93, 3, 128, 222, 60, 98,
190, 224, 2, 92, 223, 129, 99, 61, 124, 34, 192, 158, 29, 67, 161, 255,
70, 24, 250, 164, 39, 121, 155, 197, 132, 218, 56, 102, 229, 187, 89, 7,
219, 133, 103, 57, 186, 228, 6, 88, 25, 71, 165, 251, 120, 38, 196, 154,
101, 59, 217, 135, 4, 90, 184, 230, 167, 249, 27, 69, 198, 152, 122, 36,
248, 166, 68, 26, 153, 199, 37, 123, 58, 100, 134, 216, 91, 5, 231, 185,
140, 210, 48, 110, 237, 179, 81, 15, 78, 16, 242, 172, 47, 113, 147, 205,
17, 79, 173, 243, 112, 46, 204, 146, 211, 141, 111, 49, 178, 236, 14, 80,
175, 241, 19, 77, 206, 144, 114, 44, 109, 51, 209, 143, 12, 82, 176, 238,
50, 108, 142, 208, 83, 13, 239, 177, 240, 174, 76, 18, 145, 207, 45, 115,
202, 148, 118, 40, 171, 245, 23, 73, 8, 86, 180, 234, 105, 55, 213, 139,
87, 9, 235, 181, 54, 104, 138, 212, 149, 203, 41, 119, 244, 170, 72, 22,
233, 183, 85, 11, 136, 214, 52, 106, 43, 117, 151, 201, 74, 20, 246, 168,
116, 42, 200, 150, 21, 75, 169, 247, 182, 232, 10, 84, 215, 137, 107, 53
};// calculate checksum quint8 val = 0; foreach (char c, payload) val = crcTable[val ^ (quint8)(c)]; return val;
}
@PS: C-style casts should be avoided;)
-
Thanks for the tips guys! I used the code from the post above and was still getting wrong answers, but I ended up stumbling onto something that worked. I was originally creating the QByteArray payload using something like this:
@QByteArray arr;
arr.append('0x00');
arr.append('0x28');
arr.append('0x00');@That still produced incorrect results using the code above. I also tried converting that array using arr = arr.toHex(), but just got a different, still incorrect answer. I ended up creating the payload in a different manner as shown below:
@QByteArray arr;
arr.append((char)0);
arr.append((char)40);
arr.append((char)0);@Basically just converting the hex entries into their decimal equivalents and casting to a char to avoid any overloaded function confusion.
This ends up producing the correct 0xB7 result, but I'm not sure why.. Can anyone shed some like on what might have been going on? I'm going to eventually have to put more complex data types into this payload QByteArray (like floats or strings) so I want to make sure I have an understanding of how to correctly convert data types into the appropriate format.
Thanks!
-
[quote author="qwik23" date="1372373930"]Maybe a simpler question would be, is there any reason that '0x00' would be interpreted differently than (char)0?[/quote]
Yes, as we can seen.
@
(char)0 == '\x00' == '\0' == ...
@while
@
'0x00' == '\x30\x78\x30\x30'
@And according to the standard (§6.4.4.4.10)
bq. The value of an integer character constant containing more than one character (e.g., 'ab'), [...] is implementation-defined.
-
this is what you want.
copy and paste http://ideone.com/QrgYLt hear <c code> and runx^8 + x^5 + x^4 + 1 = 100110001 =0x131 right?
check: http://en.wikipedia.org/wiki/Cyclic_redundancy_check
the maxim use it reverse data bytes and reverse CRC result before final xor
below things is not reverse version.
just use this.source.c
#include <stdio.h>
#define GP 0x131 /*x^8 + x^5 + x^4 + 1 */
#define DI 0x31unsigned char crc8_table[256]; /* 8-bit table */
static int made_table=0;void init_crc8()
{
int i,j;
unsigned char crc;if (!made_table) {
for (i=0; i<256; i++) {
crc = i;
for (j=0; j<8; j++)
crc = (crc << 1) ^ ((crc & 0x80) ? DI : 0);
crc8_table[i] = crc & 0xFF;
printf("%d (0x%X),", i, crc, crc);
}
made_table=1;
}
}
int main(void) {
init_crc8();
// your code goes here
return 0;
}0 (0x0),1 (0x31),2 (0x62),3 (0x53),4 (0xC4),5 (0xF5),6 (0xA6),7 (0x97),8 (0xB9),9 (0x88),10 (0xDB),11 (0xEA),12 (0x7D),13 (0x4C),14 (0x1F),15 (0x2E),16 (0x43),17 (0x72),18 (0x21),19 (0x10),20 (0x87),21 (0xB6),22 (0xE5),23 (0xD4),24 (0xFA),25 (0xCB),26 (0x98),27 (0xA9),28 (0x3E),29 (0xF),30 (0x5C),31 (0x6D),32 (0x86),33 (0xB7),34 (0xE4),35 (0xD5),36 (0x42),37 (0x73),38 (0x20),39 (0x11),40 (0x3F),41 (0xE),42 (0x5D),43 (0x6C),44 (0xFB),45 (0xCA),46 (0x99),47 (0xA8),48 (0xC5),49 (0xF4),50 (0xA7),51 (0x96),52 (0x1),53 (0x30),54 (0x63),55 (0x52),56 (0x7C),57 (0x4D),58 (0x1E),59 (0x2F),60 (0xB8),61 (0x89),62 (0xDA),63 (0xEB),64 (0x3D),65 (0xC),66 (0x5F),67 (0x6E),68 (0xF9),69 (0xC8),70 (0x9B),71 (0xAA),72 (0x84),73 (0xB5),74 (0xE6),75 (0xD7),76 (0x40),77 (0x71),78 (0x22),79 (0x13),80 (0x7E),81 (0x4F),82 (0x1C),83 (0x2D),84 (0xBA),85 (0x8B),86 (0xD8),87 (0xE9),88 (0xC7),89 (0xF6),90 (0xA5),91 (0x94),92 (0x3),93 (0x32),94 (0x61),95 (0x50),96 (0xBB),97 (0x8A),98 (0xD9),99 (0xE8),100 (0x7F),101 (0x4E),102 (0x1D),103 (0x2C),104 (0x2),105 (0x33),106 (0x60),107 (0x51),108 (0xC6),109 (0xF7),110 (0xA4),111 (0x95),112 (0xF8),113 (0xC9),114 (0x9A),115 (0xAB),116 (0x3C),117 (0xD),118 (0x5E),119 (0x6F),120 (0x41),121 (0x70),122 (0x23),123 (0x12),124 (0x85),125 (0xB4),126 (0xE7),127 (0xD6),128 (0x7A),129 (0x4B),130 (0x18),131 (0x29),132 (0xBE),133 (0x8F),134 (0xDC),135 (0xED),136 (0xC3),137 (0xF2),138 (0xA1),139 (0x90),140 (0x7),141 (0x36),142 (0x65),143 (0x54),144 (0x39),145 (0x8),146 (0x5B),147 (0x6A),148 (0xFD),149 (0xCC),150 (0x9F),151 (0xAE),152 (0x80),153 (0xB1),154 (0xE2),155 (0xD3),156 (0x44),157 (0x75),158 (0x26),159 (0x17),160 (0xFC),161 (0xCD),162 (0x9E),163 (0xAF),164 (0x38),165 (0x9),166 (0x5A),167 (0x6B),168 (0x45),169 (0x74),170 (0x27),171 (0x16),172 (0x81),173 (0xB0),174 (0xE3),175 (0xD2),176 (0xBF),177 (0x8E),178 (0xDD),179 (0xEC),180 (0x7B),181 (0x4A),182 (0x19),183 (0x28),184 (0x6),185 (0x37),186 (0x64),187 (0x55),188 (0xC2),189 (0xF3),190 (0xA0),191 (0x91),192 (0x47),193 (0x76),194 (0x25),195 (0x14),196 (0x83),197 (0xB2),198 (0xE1),199 (0xD0),200 (0xFE),201 (0xCF),202 (0x9C),203 (0xAD),204 (0x3A),205 (0xB),206 (0x58),207 (0x69),208 (0x4),209 (0x35),210 (0x66),211 (0x57),212 (0xC0),213 (0xF1),214 (0xA2),215 (0x93),216 (0xBD),217 (0x8C),218 (0xDF),219 (0xEE),220 (0x79),221 (0x48),222 (0x1B),223 (0x2A),224 (0xC1),225 (0xF0),226 (0xA3),227 (0x92),228 (0x5),229 (0x34),230 (0x67),231 (0x56),232 (0x78),233 (0x49),234 (0x1A),235 (0x2B),236 (0xBC),237 (0x8D),238 (0xDE),239 (0xEF),240 (0x82),241 (0xB3),242 (0xE0),243 (0xD1),244 (0x46),245 (0x77),246 (0x24),247 (0x15),248 (0x3B),249 (0xA),250 (0x59),251 (0x68),252 (0xFF),253 (0xCE),254 (0x9D),255 (0xAC), - See more at: http://ideone.com/QrgYLt#sthash.tl2ydB9y.dpuf