65 lines
1.6 KiB
C
65 lines
1.6 KiB
C
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
|
|
#define DELTA 0x9E3779B9
|
|
#define ROUNDS 32
|
|
#define BLOCK_SIZE 24
|
|
|
|
void encrypt(uint32_t v[2], uint32_t const key[4]) {
|
|
uint32_t v0 = v[0], v1 = v[1], sum = 0;
|
|
for (int i = 0; i < ROUNDS; i++) {
|
|
v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + key[sum & 3]);
|
|
sum += DELTA;
|
|
v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + key[(sum >> 11) & 3]);
|
|
}
|
|
v[0] = v0;
|
|
v[1] = v1;
|
|
}
|
|
|
|
void xtea_hash(const char *filename, uint64_t *hash) {
|
|
int fd = open(filename, O_RDONLY);
|
|
if (fd < 0) {
|
|
perror("Error opening file");
|
|
exit(1);
|
|
}
|
|
|
|
uint64_t current_hash = 0;
|
|
uint8_t buffer[BLOCK_SIZE];
|
|
ssize_t bytes_read;
|
|
|
|
while ((bytes_read = read(fd, buffer, BLOCK_SIZE)) > 0) {
|
|
if (bytes_read < BLOCK_SIZE) {
|
|
memset(buffer + bytes_read, 0, BLOCK_SIZE - bytes_read);
|
|
buffer[BLOCK_SIZE - 1] = BLOCK_SIZE - bytes_read;
|
|
}
|
|
|
|
uint32_t x[2];
|
|
uint32_t k[4];
|
|
memcpy(x, buffer, 8);
|
|
memcpy(k, buffer + 8, 16);
|
|
|
|
encrypt(x, k);
|
|
uint64_t hashed_block = ((uint64_t)x[0] << 32) | x[1];
|
|
current_hash ^= hashed_block;
|
|
}
|
|
|
|
close(fd);
|
|
*hash = current_hash;
|
|
}
|
|
|
|
int main(int argc, char *argv[]) {
|
|
if (argc != 2) {
|
|
fprintf(stderr, "Usage: %s <file>\n", argv[0]);
|
|
return 1;
|
|
}
|
|
|
|
uint64_t hash;
|
|
xtea_hash(argv[1], &hash);
|
|
printf("Hash: %016lx\n", hash);
|
|
return 0;
|
|
}
|