Last active
January 21, 2021 17:30
-
-
Save lh3/1246b864e9f38870a0bd to your computer and use it in GitHub Desktop.
Source code for computing CRC32 and SHA1 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 <zlib.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#define BUF_LEN 0x100000 | |
int main(int argc, char *argv[]) | |
{ | |
uLong crc = crc32(0L, Z_NULL, 0); | |
unsigned char buf[BUF_LEN]; | |
int l, fd; | |
if (argc < 2) { | |
fprintf(stderr, "Usage: crc32 <file>\n"); | |
return 1; | |
} | |
fd = open(argv[1], O_RDONLY); | |
while ((l = read(fd, buf, BUF_LEN)) > 0) | |
crc = crc32(crc, buf, l); | |
printf("%lx %s\n", (long)crc, argv[1]); | |
close(fd); | |
return 0; | |
} |
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
/* from ghostscript; in public domain */ | |
#include <stdio.h> | |
#include <stdint.h> | |
#include <string.h> | |
typedef struct { | |
uint32_t state[5]; | |
uint32_t count[2]; | |
uint8_t buffer[64]; | |
} SHA1_CTX; | |
#define SHA1_DIGEST_SIZE 20 | |
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | |
#ifdef WORDS_BIGENDIAN | |
#define blk0(i) block->l[i] | |
#else | |
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ | |
|(rol(block->l[i],8)&0x00FF00FF)) | |
#endif | |
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ | |
^block->l[(i+2)&15]^block->l[i&15],1)) | |
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ | |
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); | |
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); | |
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); | |
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); | |
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); | |
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) | |
{ | |
uint32_t a, b, c, d, e; | |
typedef union { | |
uint8_t c[64]; | |
uint32_t l[16]; | |
} CHAR64LONG16; | |
CHAR64LONG16* block; | |
block = (CHAR64LONG16*)buffer; | |
/* Copy context->state[] to working vars */ | |
a = state[0]; | |
b = state[1]; | |
c = state[2]; | |
d = state[3]; | |
e = state[4]; | |
/* 4 rounds of 20 operations each. Loop unrolled. */ | |
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); | |
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); | |
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); | |
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); | |
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); | |
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); | |
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); | |
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); | |
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); | |
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); | |
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); | |
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); | |
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); | |
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); | |
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); | |
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); | |
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); | |
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); | |
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); | |
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); | |
/* Add the working vars back into context.state[] */ | |
state[0] += a; | |
state[1] += b; | |
state[2] += c; | |
state[3] += d; | |
state[4] += e; | |
/* Wipe variables */ | |
a = b = c = d = e = 0; | |
} | |
/* SHA1Init - Initialize new context */ | |
void SHA1_Init(SHA1_CTX* context) | |
{ | |
/* SHA1 initialization constants */ | |
context->state[0] = 0x67452301; | |
context->state[1] = 0xEFCDAB89; | |
context->state[2] = 0x98BADCFE; | |
context->state[3] = 0x10325476; | |
context->state[4] = 0xC3D2E1F0; | |
context->count[0] = context->count[1] = 0; | |
} | |
/* Run your data through this. */ | |
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) | |
{ | |
size_t i, j; | |
j = (context->count[0] >> 3) & 63; | |
if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; | |
context->count[1] += (len >> 29); | |
if ((j + len) > 63) { | |
memcpy(&context->buffer[j], data, (i = 64-j)); | |
SHA1_Transform(context->state, context->buffer); | |
for ( ; i + 63 < len; i += 64) { | |
SHA1_Transform(context->state, data + i); | |
} | |
j = 0; | |
} | |
else i = 0; | |
memcpy(&context->buffer[j], &data[i], len - i); | |
} | |
/* Add padding and return the message digest. */ | |
void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) | |
{ | |
uint32_t i; | |
uint8_t finalcount[8]; | |
for (i = 0; i < 8; i++) { | |
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] | |
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ | |
} | |
SHA1_Update(context, (uint8_t *)"\200", 1); | |
while ((context->count[0] & 504) != 448) { | |
SHA1_Update(context, (uint8_t *)"\0", 1); | |
} | |
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ | |
for (i = 0; i < SHA1_DIGEST_SIZE; i++) { | |
digest[i] = (uint8_t) | |
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); | |
} | |
/* Wipe variables */ | |
i = 0; | |
memset(context->buffer, 0, 64); | |
memset(context->state, 0, 20); | |
memset(context->count, 0, 8); | |
memset(finalcount, 0, 8); /* SWR */ | |
} | |
#include <fcntl.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#define BUF_LEN 0x100000 | |
int main(int argc, char *argv[]) | |
{ | |
unsigned char buf[BUF_LEN]; | |
int l, fd; | |
SHA1_CTX ctx; | |
unsigned char sha1[SHA1_DIGEST_SIZE]; | |
if (argc < 2) { | |
fprintf(stderr, "Usage: sha1gs <file>\n"); | |
return 1; | |
} | |
SHA1_Init(&ctx); | |
fd = open(argv[1], O_RDONLY); | |
while ((l = read(fd, buf, BUF_LEN)) > 0) | |
SHA1_Update(&ctx, buf, l); | |
SHA1_Final(&ctx, sha1); | |
for (l = 0; l < SHA1_DIGEST_SIZE; ++l) | |
printf("%x", sha1[l]); | |
printf(" %s\n", argv[1]); | |
close(fd); | |
return 0; | |
} |
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
/* lh3 note: it is slow */ | |
/* This code is public-domain - it is based on libcrypt placed in the public domain by Wei Dai and other contributors. */ | |
#include <string.h> | |
#include <stdint.h> | |
#define HASH_LENGTH 20 | |
#define BLOCK_LENGTH 64 | |
typedef struct sha1nfo { | |
union { uint8_t b[BLOCK_LENGTH]; uint32_t w[BLOCK_LENGTH/4]; } buf; | |
uint8_t bufOffset; | |
union { uint8_t b[HASH_LENGTH]; uint32_t w[HASH_LENGTH/4]; } state; | |
uint32_t byteCount; | |
uint8_t keyBuffer[BLOCK_LENGTH]; | |
uint8_t innerHash[HASH_LENGTH]; | |
} sha1nfo; | |
void sha1_init(sha1nfo *s) | |
{ | |
const uint8_t table[] = { 0x01,0x23,0x45,0x67, 0x89,0xab,0xcd,0xef, 0xfe,0xdc,0xba,0x98, 0x76,0x54,0x32,0x10, 0xf0,0xe1,0xd2,0xc3 }; | |
memcpy(s->state.b, table, HASH_LENGTH); | |
s->byteCount = 0; | |
s->bufOffset = 0; | |
} | |
#define rol32(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) | |
static void sha1_hashBlock(sha1nfo *s) | |
{ | |
uint32_t i, t, a = s->state.w[0], b = s->state.w[1], c = s->state.w[2], d = s->state.w[3], e = s->state.w[4]; | |
for (i = 0; i < 80; i++) { | |
if (i >= 16) { | |
t = s->buf.w[(i+13)&15] ^ s->buf.w[(i+8)&15] ^ s->buf.w[(i+2)&15] ^ s->buf.w[i&15]; | |
s->buf.w[i&15] = rol32(t, 1); | |
} | |
if (i < 20) t = 0x5a827999 + (d ^ (b & (c ^ d))); | |
else if (i < 40) t = 0x6ed9eba1 + (b ^ c ^ d); | |
else if (i < 60) t = 0x8f1bbcdc + ((b & c) | (d & (b | c))); | |
else t = 0xca62c1d6 + (b ^ c ^ d); | |
t += rol32(a, 5) + e + s->buf.w[i&15]; | |
e = d; d = c; c = rol32(b, 30); b = a; a = t; | |
} | |
s->state.w[0] += a; s->state.w[1] += b; s->state.w[2] += c; s->state.w[3] += d; s->state.w[4] += e; | |
} | |
static inline void sha1_add(sha1nfo *s, uint8_t data) | |
{ | |
s->buf.b[s->bufOffset ^ 3] = data; | |
if (++s->bufOffset == BLOCK_LENGTH) { | |
sha1_hashBlock(s); | |
s->bufOffset = 0; | |
} | |
} | |
inline void sha1_write1(sha1nfo *s, uint8_t data) | |
{ | |
++s->byteCount; | |
sha1_add(s, data); | |
} | |
inline void sha1_write(sha1nfo *s, const char *data, size_t len) | |
{ | |
while (len--) sha1_write1(s, (uint8_t)*data++); | |
} | |
const uint8_t *sha1_final(sha1nfo *s) | |
{ | |
int i; | |
sha1_add(s, 0x80); | |
while (s->bufOffset != 56) sha1_add(s, 0); | |
sha1_add(s, 0); | |
sha1_add(s, 0); | |
sha1_add(s, 0); | |
sha1_add(s, s->byteCount >> 29); | |
sha1_add(s, s->byteCount >> 21); | |
sha1_add(s, s->byteCount >> 13); | |
sha1_add(s, s->byteCount >> 5); | |
sha1_add(s, s->byteCount << 3); | |
for (i = 0; i < 5; ++i) { | |
uint32_t a = s->state.w[i]; | |
s->state.w[i] = a<<24 | (a<<8&0x00ff0000) | (a>>8&0x0000ff00) | a>>24; | |
} | |
return s->state.b; | |
} | |
#include <unistd.h> | |
#include <fcntl.h> | |
#include <stdio.h> | |
#define BUF_LEN 0x100000 | |
int main(int argc, char *argv[]) | |
{ | |
char buf[BUF_LEN]; | |
int l, fd; | |
sha1nfo s; | |
const uint8_t *sha1; | |
if (argc < 2) { | |
fprintf(stderr, "Usage: sha1oauth <file>\n"); | |
return 1; | |
} | |
sha1_init(&s); | |
fd = open(argv[1], O_RDONLY); | |
while ((l = read(fd, buf, BUF_LEN)) > 0) | |
sha1_write(&s, buf, l); | |
sha1 = sha1_final(&s); | |
for (l = 0; l < HASH_LENGTH; ++l) | |
printf("%x", sha1[l]); | |
printf(" %s\n", argv[1]); | |
close(fd); | |
return 0; | |
} |
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 <fcntl.h> | |
#include <stdio.h> | |
#include <unistd.h> | |
#include <openssl/sha.h> | |
#define BUF_LEN 0x100000 | |
int main(int argc, char *argv[]) | |
{ | |
unsigned char buf[BUF_LEN]; | |
int l, fd; | |
SHA_CTX ctx; | |
unsigned char sha1[SHA_DIGEST_LENGTH]; | |
if (argc < 2) { | |
fprintf(stderr, "Usage: sha1openssl <file>\n"); | |
return 1; | |
} | |
SHA_Init(&ctx); | |
fd = open(argv[1], O_RDONLY); | |
while ((l = read(fd, buf, BUF_LEN)) > 0) | |
SHA1_Update(&ctx, buf, l); | |
SHA1_Final(sha1, &ctx); | |
for (l = 0; l < SHA_DIGEST_LENGTH; ++l) | |
printf("%x", sha1[l]); | |
printf(" %s\n", argv[1]); | |
close(fd); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment