diff --git a/network-poc/static/index.html b/network-poc/static/index.html
index ee83c0d..a91819d 100644
--- a/network-poc/static/index.html
+++ b/network-poc/static/index.html
@@ -1989,7 +1989,18 @@
if (!card) return;
const files = projectFiles[cardId];
- // Luodaan ZIP ilman ulkoisia kirjastoja (yksinkertainen uncompressed ZIP)
+ // CRC-32 laskenta ZIP-tiedostoille
+ function crc32(bytes) {
+ let crc = 0xFFFFFFFF;
+ for (let i = 0; i < bytes.length; i++) {
+ crc ^= bytes[i];
+ for (let j = 0; j < 8; j++) {
+ crc = (crc >>> 1) ^ (crc & 1 ? 0xEDB88320 : 0);
+ }
+ }
+ return (crc ^ 0xFFFFFFFF) >>> 0;
+ }
+
const entries = Object.entries(files);
const parts = [];
const centralDir = [];
@@ -1998,6 +2009,7 @@
for (const [name, content] of entries) {
const nameBytes = new TextEncoder().encode(name);
const contentBytes = new TextEncoder().encode(content);
+ const crc = crc32(contentBytes);
// Local file header
const header = new Uint8Array(30 + nameBytes.length);
@@ -2005,8 +2017,9 @@
view.setUint32(0, 0x04034b50, true); // Signature
view.setUint16(4, 20, true); // Version needed
view.setUint16(8, 0, true); // Method: store
- view.setUint32(18, contentBytes.length, true); // Compressed size
- view.setUint32(22, contentBytes.length, true); // Uncompressed size
+ view.setUint32(14, crc, true); // CRC-32
+ view.setUint32(18, contentBytes.length, true);
+ view.setUint32(22, contentBytes.length, true);
view.setUint16(26, nameBytes.length, true);
header.set(nameBytes, 30);
@@ -2016,6 +2029,7 @@
cdView.setUint32(0, 0x02014b50, true);
cdView.setUint16(4, 20, true);
cdView.setUint16(6, 20, true);
+ cdView.setUint32(16, crc, true); // CRC-32
cdView.setUint32(20, contentBytes.length, true);
cdView.setUint32(24, contentBytes.length, true);
cdView.setUint16(28, nameBytes.length, true);