Last active
December 6, 2017 14:36
-
-
Save ecsv/c7dee37e295fdca7f87043afa2818075 to your computer and use it in GitHub Desktop.
zyxel checksum
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <assert.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <string.h> | |
uint16_t zyxel_checksum1(const uint8_t *start, const uint8_t *end) | |
{ | |
const uint8_t *pos; | |
uint32_t crc; | |
size_t len; | |
size_t i; | |
crc = 0; | |
pos = start; | |
len = end - start + 1; | |
if (len > 0) { | |
for (i = 0; i < len; i++) { | |
crc += pos[i]; | |
if (crc > UINT16_MAX) { | |
crc++; | |
crc &= UINT16_MAX; | |
} | |
} | |
/* don't ask me, I have no idea - this is actually a out of | |
* bounds read in some situations | |
*/ | |
if (len % 2) { | |
crc += end[1] << 8; | |
if (crc > UINT16_MAX) { | |
crc++; | |
crc &= UINT16_MAX; | |
} | |
} | |
} | |
return (uint16_t)crc; | |
} | |
uint16_t zyxel_checksum2(FILE *f, size_t start, size_t len) | |
{ | |
const uint8_t *pos; | |
uint8_t buf[2048]; | |
size_t readsize; | |
uint32_t crc; | |
size_t ret; | |
size_t i; | |
crc = 0; | |
fseek(f, start, SEEK_SET); | |
while (len > 0 && !feof(f)) { | |
readsize = len; | |
if (readsize > sizeof(buf)) | |
readsize = sizeof(buf); | |
len -= readsize; | |
ret = fread(&buf, 1, readsize, f); | |
assert(ret == readsize); | |
pos = buf; | |
for (i = 0; i < readsize; i++) { | |
crc += pos[i]; | |
if (crc > UINT16_MAX) { | |
crc++; | |
crc &= UINT16_MAX; | |
} | |
} | |
/* don't ask me, I have no idea */ | |
if (readsize % 2) { | |
crc += buf[readsize] << 8; | |
if (crc > UINT16_MAX) { | |
crc++; | |
crc &= UINT16_MAX; | |
} | |
} | |
} | |
return (uint16_t)crc; | |
} | |
int main(void) | |
{ | |
uint16_t crc; | |
FILE *in; | |
/* dd if=/dev/urandom of=test.img count=2000 */ | |
printf("make sure to create test file with:\ndd if=/dev/urandom of=test.img count=2000\n\n"); | |
in = fopen("test.img", "rb"); | |
assert(in); | |
static const char *test = "abcdefg"; | |
crc = zyxel_checksum1(test, &test[strlen(test) - 1]); | |
printf("Memory test: 0x%04x\n", crc); | |
crc = zyxel_checksum2(in, 0, 1024000); | |
printf("Checksum of test.img: 0x%04x\n", crc); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment