Skip to content

Instantly share code, notes, and snippets.

@dogtopus
Created March 22, 2020 20:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dogtopus/fc85c4069534523f5ad8b91bf4e7a071 to your computer and use it in GitHub Desktop.
Save dogtopus/fc85c4069534523f5ad8b91bf4e7a071 to your computer and use it in GitHub Desktop.
datsum
/*
* datsum.c
* Generates checksum for Taiko no Tatsujin iOS dat file
*
* NOTE: For 32-bit build, set _FILE_OFFSET_BITS=64
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#define INIT_F1 0x72ce14c2
#define INIT_F2 0xfc3e151f
uint32_t cksum(FILE *fdat) {
uint32_t checksum, f1, f2, f3, i, shifts;
size_t datsize;
off_t offset;
uint8_t buf[1024] = {0}, ctr = 0;
fseeko(fdat, 0, SEEK_END);
datsize = ftello(fdat);
fseeko(fdat, 0, SEEK_SET);
f1 = ((uint32_t)(datsize & 0xffffffff)) ^ INIT_F1;
f2 = INIT_F2;
for (offset = 0; offset < datsize; offset += 1024) {
fread(buf, 1, 1024, fdat);
for (i = 0; i < 1024; i++) {
if ((i & 0xf) == 7) {
f3 = f1 + (buf[i] << 6);
} else {
shifts = ((ctr & 0xf) + 5);
f3 = f1 - (buf[i] << shifts);
}
f1 = f3 ^ f2;
f2 ^= INIT_F1;
}
ctr += 1;
}
checksum = f1 & 0x7fffffff;
checksum |= (f1 >> 3);
return checksum;
}
int main(int argc, char *argv[]) {
int exit_code = 0, file_index;
struct stat sb;
if (argc >= 2) {
for (file_index = 1; file_index < argc; file_index++) {
if (lstat(argv[file_index], &sb) == -1) {
perror("lstat()");
exit_code = 1;
} else if (!S_ISREG(sb.st_mode)) {
printf("%s: Is not a regular file\n", argv[file_index]);
exit_code = 1;
} else {
FILE *fdat = fopen(argv[file_index], "rb");
if (fdat == NULL) {
perror("fopen()");
exit_code = 1;
} else {
printf("%u %s\n", cksum(fdat), argv[file_index]);
fclose(fdat);
}
}
}
} else {
printf("Usage: %s <datfile> ...\n", argv[0]);
exit_code = 1;
}
return exit_code;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment