>ask Grok for code that puts files into a zip file
>works but 32-bit only (4 GB size limit)
>ask for 64-bit version
>doesn't work
>ask ChatGPT
>gives a 32-bit version despite me asking for 64-bit
>ask for 64-bit version
>breaks because I forgot to enable cookies
Had to ask Grok again with even more specific requirements. I have no idea how correct this actually is, but it seems to work, maybe some day I'll bother to check some kind of documentation to make sure:
typedef struct {
char* name;
char* path;
u64 offset;
u64 size;
u32 crc;
} Zip_file;
static u32 zip_crc32 (u32 crc, u64 length, u8* data) {
for (u64 i=0; i<length; i++) {
crc ^= data[i];
for (int j=0; j<8; j++) crc = (crc >> 1) ^ (0xEDB88320 * (crc & 1));
}
return ~crc;
}
static int create_zip (char* path, int file_count, Zip_file* files) {
File zip = create_file(path);
#define WRITE_U16(value) do{ u16 v = value; append_to_file(&zip, sizeof(v), &v); }while(0)
#define WRITE_U32(value) do{ u32 v = value; append_to_file(&zip, sizeof(v), &v); }while(0)
#define WRITE_U64(value) do{ u64 v = value; append_to_file(&zip, sizeof(v), &v); }while(0)
#define WRITE(length, data) do{ append_to_file(&zip, length, data); }while(0)
for (int i=0; i<file_count; i++) {
Zip_file* file = files+i;
u64 f_size = 0;
void* f = NULL;
read_file(file->path, &f_size, &f);
if (!f_size) {
printf("Failed %s\n", file->path);
delete_file(&zip);
return 1;
}
file->offset = zip.size;
file->size = f_size;
file->crc = zip_crc32(0xFFFFFFFF, f_size, (u8*)f);
WRITE_U32(0x04034b50);
WRITE_U16(45);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U32(file->crc);
WRITE_U32(0xFFFFFFFF);
WRITE_U32(0xFFFFFFFF);
WRITE_U16(strlen(file->name));
WRITE_U16(28);
WRITE(strlen(file->name), file->name);
WRITE_U16(0x0001);
WRITE_U16(24);
WRITE_U64(file->size);
WRITE_U64(file->size);
WRITE(f_size, f);
free_file(&f);
}
u64 central_dir_start = zip.size;
for (int i=0; i<file_count; i++) {
Zip_file* file = files+i;
WRITE_U32(0x02014b50);
WRITE_U16(45);
WRITE_U16(45);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U32(file->crc);
WRITE_U32(0xFFFFFFFF);
WRITE_U32(0xFFFFFFFF);
WRITE_U16(strlen(file->name));
WRITE_U16(32);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U32(0);
WRITE_U32(0xFFFFFFFF);
WRITE(strlen(file->name), file->name);
WRITE_U16(0x0001);
WRITE_U16(28);
WRITE_U64(file->size);
WRITE_U64(file->size);
WRITE_U64(file->offset);
WRITE_U32(0);
}
u64 central_dir_size = zip.size - central_dir_start;
u64 zip64_eocd_offset = zip.size;
WRITE_U32(0x06064b50);
WRITE_U64(44);
WRITE_U16(45);
WRITE_U16(45);
WRITE_U32(0);
WRITE_U32(0);
WRITE_U64(file_count);
WRITE_U64(file_count);
WRITE_U64(central_dir_size);
WRITE_U64(central_dir_start);
WRITE_U32(0x07064b50);
WRITE_U32(0);
WRITE_U64(zip64_eocd_offset);
WRITE_U32(1);
WRITE_U32(0x06054b50);
WRITE_U16(0);
WRITE_U16(0);
WRITE_U16(0xFFFF);
WRITE_U16(0xFFFF);
WRITE_U32(0xFFFFFFFF);
WRITE_U32(0xFFFFFFFF);
WRITE_U16(0);
close_file(&zip);
return 0;
}
void main () {
Zip_file files [] = {
{.name="items.json", .path="C:/foo/items.json"},
{.name="sprites.png", .path="C:/foo/sprites.png"},
{.name="info.txt", .path="C:/foo/info.txt"},
};
create_zip("C:/foo/test.zip", sizeof(files)/sizeof(Zip_file), files);
}
On one hand it's great how I can get AI to handle file formats and APIs for me that I never had the motivation to research, but on the other hand it's concerning how often it doesn't work or has something weird about it. I just really don't want to start researching this kind of shit myself at all.