stat2025 commited on
Commit
6ae0d35
·
verified ·
1 Parent(s): 6295292

Update data generator and researcher maps

Browse files
Files changed (1) hide show
  1. generate-data.mjs +45 -15
generate-data.mjs CHANGED
@@ -2,7 +2,7 @@ import fs from "node:fs/promises";
2
  import crypto from "node:crypto";
3
  import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
4
 
5
- const [inputPath, outputPath, password = "20302030"] = process.argv.slice(2);
6
 
7
  const MAP_URLS = [
8
  ["أماني مصطفى عبدالله الطيب", "https://stat2025-map.static.hf.space/Rahn/01.html"],
@@ -89,6 +89,41 @@ function mapUrlFor(researcher) {
89
  return partial?.[1] || "";
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  if (!inputPath || !outputPath) {
93
  console.error("Usage: node generate-data.mjs <input.xlsx> <output.js> [password]");
94
  process.exitCode = 1;
@@ -119,7 +154,7 @@ if (!inputPath || !outputPath) {
119
  ? "statement"
120
  : "none";
121
 
122
- rows.push({
123
  researcher,
124
  establishmentName,
125
  contractNumber: clean(source[3]),
@@ -135,7 +170,9 @@ if (!inputPath || !outputPath) {
135
  unifiedNumber: clean(source[12]),
136
  activityCode: clean(source[13]),
137
  activity: clean(source[14]),
138
- });
 
 
139
  }
140
 
141
  const counts = new Map();
@@ -155,20 +192,13 @@ if (!inputPath || !outputPath) {
155
  });
156
 
157
  const iterations = 310000;
158
- const salt = crypto.randomBytes(16);
159
- const iv = crypto.randomBytes(12);
160
- const key = crypto.pbkdf2Sync(password, salt, iterations, 32, "sha256");
161
- const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
162
- const encrypted = Buffer.concat([cipher.update(plainPayload, "utf8"), cipher.final()]);
163
- const combined = Buffer.concat([encrypted, cipher.getAuthTag()]);
164
  const output = [
165
  "/* Generated encrypted data. Rebuild this file from the source workbook. */",
166
- "const ENCRYPTED_DATA = Object.freeze({",
167
- ` iterations: ${iterations},`,
168
- ` salt: "${salt.toString("base64")}",`,
169
- ` iv: "${iv.toString("base64")}",`,
170
- ` payload: "${combined.toString("base64")}",`,
171
- "});",
172
  "",
173
  ].join("\n");
174
 
 
2
  import crypto from "node:crypto";
3
  import { FileBlob, SpreadsheetFile } from "@oai/artifact-tool";
4
 
5
+ const [inputPath, outputPath, password = "20302030", supervisorPassword = "1448"] = process.argv.slice(2);
6
 
7
  const MAP_URLS = [
8
  ["أماني مصطفى عبدالله الطيب", "https://stat2025-map.static.hf.space/Rahn/01.html"],
 
89
  return partial?.[1] || "";
90
  }
91
 
92
+ function sampleKey(row) {
93
+ const parts = [
94
+ row.commercialRecord,
95
+ row.contractNumber,
96
+ row.establishmentName,
97
+ row.researcher,
98
+ ].map(normalize);
99
+ return crypto.createHash("sha256").update(parts.join("|")).digest("hex").slice(0, 24);
100
+ }
101
+
102
+ function encryptPayload(plainPayload, secret, iterations) {
103
+ const salt = crypto.randomBytes(16);
104
+ const iv = crypto.randomBytes(12);
105
+ const key = crypto.pbkdf2Sync(secret, salt, iterations, 32, "sha256");
106
+ const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
107
+ const encrypted = Buffer.concat([cipher.update(plainPayload, "utf8"), cipher.final()]);
108
+ return {
109
+ iterations,
110
+ salt: salt.toString("base64"),
111
+ iv: iv.toString("base64"),
112
+ payload: Buffer.concat([encrypted, cipher.getAuthTag()]).toString("base64"),
113
+ };
114
+ }
115
+
116
+ function encryptedBlock(name, encrypted) {
117
+ return [
118
+ `const ${name} = Object.freeze({`,
119
+ ` iterations: ${encrypted.iterations},`,
120
+ ` salt: "${encrypted.salt}",`,
121
+ ` iv: "${encrypted.iv}",`,
122
+ ` payload: "${encrypted.payload}",`,
123
+ "});",
124
+ ].join("\n");
125
+ }
126
+
127
  if (!inputPath || !outputPath) {
128
  console.error("Usage: node generate-data.mjs <input.xlsx> <output.js> [password]");
129
  process.exitCode = 1;
 
154
  ? "statement"
155
  : "none";
156
 
157
+ const row = {
158
  researcher,
159
  establishmentName,
160
  contractNumber: clean(source[3]),
 
170
  unifiedNumber: clean(source[12]),
171
  activityCode: clean(source[13]),
172
  activity: clean(source[14]),
173
+ };
174
+ row.sampleKey = sampleKey(row);
175
+ rows.push(row);
176
  }
177
 
178
  const counts = new Map();
 
192
  });
193
 
194
  const iterations = 310000;
195
+ const researcherEncrypted = encryptPayload(plainPayload, password, iterations);
196
+ const supervisorEncrypted = encryptPayload(plainPayload, supervisorPassword, iterations);
 
 
 
 
197
  const output = [
198
  "/* Generated encrypted data. Rebuild this file from the source workbook. */",
199
+ encryptedBlock("ENCRYPTED_DATA", researcherEncrypted),
200
+ "",
201
+ encryptedBlock("SUPERVISOR_ENCRYPTED_DATA", supervisorEncrypted),
 
 
 
202
  "",
203
  ].join("\n");
204