@ddunigma/node 3.0.3 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,14 +10,14 @@ V2 추가사항
10
10
 
11
11
  ### Credits
12
12
 
13
- - Original Python Implementation by:
13
+ - Origin implementation by:
14
14
  - [@i3ls](https://github.com/i3l3)
15
15
  - [@gunu3371](https://github.com/gunu3371)
16
16
  - Original Repository: [ddunigma](https://github.com/i3l3/ddunigma)
17
17
 
18
18
  ## Requirements
19
19
 
20
- - **Node.js >= 18.0.0**
20
+ - **Node.js >= 22.0.0**
21
21
 
22
22
  ## Install
23
23
 
@@ -51,7 +51,7 @@ const input = new Uint8Array([0, 1, 127, 128, 255]);
51
51
 
52
52
  const encoded = ddu.encode(input);
53
53
  const bytes = ddu.decodeToUint8Array(encoded);
54
- const buffer = ddu.decodeToBuffer(encoded); // Node.js Buffer
54
+ const buffer = ddu.decodeToBuffer(encoded); // Node.js entry only
55
55
  ```
56
56
 
57
57
  ## Presets
@@ -93,6 +93,9 @@ const hangulCoda = new Ddu64(["가", "나", "다", "라"], "뭐", {
93
93
  // → 가, 각, 갂, 갇, 나, 낙, 낚, 낟, 다, 닥, 닦, 닫, 라, 락, 랔, 랗 (16문자)
94
94
  ```
95
95
 
96
+ 커스텀 charset의 각 심볼과 `paddingChar`는 단일 UTF-16 코드 유닛 문자여야 합니다.
97
+ 이모지처럼 surrogate pair가 필요한 문자나 여러 문자로 이루어진 심볼은 지원하지 않습니다.
98
+
96
99
  ## CharsetBuilder
97
100
 
98
101
  ```typescript
@@ -127,6 +130,8 @@ const decoded = ddu.decode(encoded);
127
130
  ```
128
131
 
129
132
  압축은 원본보다 작아질 때만 적용됩니다. 압축 결과가 더 크면 비압축으로 저장됩니다.
133
+ 브라우저 진입점은 `deflate-raw`를 지원하는 CompressionStream/DecompressionStream 런타임에서 압축을 사용합니다.
134
+ 브라우저 Brotli는 런타임 지원 여부를 feature detection으로 확인하며, Web API 특성상 `compressionLevel`은 적용되지 않을 수 있습니다.
130
135
 
131
136
  ## Encryption
132
137
 
@@ -151,6 +156,9 @@ const dduPbkdf2 = new Ddu64({
151
156
  });
152
157
  ```
153
158
 
159
+ PBKDF2 `iterations`는 기본값이 `210_000`이며, `10_000` 미만의 양수는 `10_000`으로 보정됩니다.
160
+ 0 이하 또는 유한하지 않은 값은 기본값으로 대체됩니다.
161
+
154
162
  ## Checksum
155
163
 
156
164
  ```typescript
@@ -206,7 +214,8 @@ const encoded = await ddu.encodeAsync("browser text");
206
214
  const decoded = await ddu.decodeAsync(encoded);
207
215
  ```
208
216
 
209
- Node.js에서도 async 메서드를 사용할 수 있습니다. 브라우저 진입점(`@ddunigma/node/browser`)은 Node.js 내장 모듈을 임포트하지 않습니다.
217
+ Node.js에서도 async 메서드를 사용할 수 있습니다. v4부터 루트 진입점(`@ddunigma/node`)은 런타임 조건형 export를 사용하므로 브라우저 번들러와 Workers 계열 런타임에서는 BrowserAdapter 경로로 해석됩니다. 명시적인 브라우저 경로가 필요하면 `@ddunigma/node/browser`를 사용하세요.
218
+ 코어 진입점(`@ddunigma/node/core`)은 기본 인코딩/디코딩만 포함하며, 압축/암호화가 필요하면 명시적으로 어댑터를 전달하세요.
210
219
 
211
220
  ## Web Streams
212
221
 
@@ -225,21 +234,26 @@ const encodedStream = readableByteStream.pipeThrough(
225
234
  const decodedStream = encodedStream.pipeThrough(createReadableDecodeStream(ddu));
226
235
  ```
227
236
 
237
+ 인코딩 스트림은 압축/암호화/체크섬이 꺼져 있고 2의 제곱수 charset일 때 청크 단위로 즉시 출력합니다.
238
+ 디코딩 스트림은 footer의 압축/암호화 메타데이터를 최종 신뢰하므로 payload를 모아 `flush`에서 처리합니다.
239
+
228
240
  ## WASM Acceleration
229
241
 
230
242
  ```typescript
231
243
  import { Ddu64, preloadWasm } from "@ddunigma/node";
232
244
 
233
- await preloadWasm(); // 선택적 사전 로드
245
+ await preloadWasm(); // 동기 encode/decode hot path에서 WASM을 쓰려면 먼저 완료되어야 함
234
246
 
235
247
  const ddu = new Ddu64({
236
248
  wasmThreshold: 4096, // 이 크기 이상일 때 WASM 사용
249
+ // wasmThreshold: Infinity, // WASM hot path 비활성화
237
250
  });
238
251
 
239
252
  const encoded = ddu.encode(new Uint8Array(1024 * 1024));
240
253
  ```
241
254
 
242
- WASM을 사용할 없으면 JavaScript로 자동 폴백됩니다.
255
+ `encode()`/`decode()`의 동기 hot path는 이미 로드된 WASM만 사용합니다.
256
+ `preloadWasm()`이 완료되지 않았거나 WASM을 사용할 수 없으면 JavaScript로 폴백됩니다.
243
257
 
244
258
  ## Progress Callback
245
259
 
@@ -272,10 +286,33 @@ const ddu = new Ddu64({
272
286
  });
273
287
  ```
274
288
 
289
+ ## Custom Errors
290
+
291
+ ```typescript
292
+ import { Ddu64, Ddu64ErrorCode, isDdu64Error } from "@ddunigma/node";
293
+
294
+ const ddu = new Ddu64({ checksum: true });
295
+
296
+ try {
297
+ ddu.decode(tamperedInput);
298
+ } catch (err) {
299
+ if (isDdu64Error(err) && err.code === Ddu64ErrorCode.ChecksumMismatch) {
300
+ // 체크섬 불일치 처리
301
+ }
302
+ }
303
+ ```
304
+
305
+ 인코딩, 디코딩, 압축, 암호화, 체크섬, charset, 크기 제한, adapter, stream 실패는
306
+ `Ddu64Error` 계열로 래핑됩니다. 모든 공개 진입점(`@ddunigma/node`,
307
+ `@ddunigma/node/browser`, `@ddunigma/node/core`)에서 같은 에러 타입과
308
+ `Ddu64ErrorCode`를 export합니다.
309
+
275
310
  ---
276
311
 
277
312
  ## API
278
313
 
314
+ ### Node Entry
315
+
279
316
  ```typescript
280
317
  class Ddu64 {
281
318
  encode(data: string | Uint8Array, options?: DduOptions): string;
@@ -290,11 +327,48 @@ class Ddu64 {
290
327
 
291
328
  getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
292
329
  getCharSetInfo(): CharSetInfo;
330
+ }
331
+ ```
332
+
333
+ ### Browser Entry
334
+
335
+ ```typescript
336
+ class Ddu64 {
337
+ encode(data: string | Uint8Array, options?: DduOptions): string;
338
+ decode(encoded: string, options?: DduOptions): string;
339
+ decodeToUint8Array(encoded: string, options?: DduOptions): Uint8Array;
293
340
 
294
- static setWorkerPoolSize(n: number): void;
341
+ encodeAsync(data: string | Uint8Array, options?: DduOptions): Promise<string>;
342
+ decodeAsync(encoded: string, options?: DduOptions): Promise<string>;
343
+ decodeToUint8ArrayAsync(encoded: string, options?: DduOptions): Promise<Uint8Array>;
344
+
345
+ getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
346
+ getCharSetInfo(): CharSetInfo;
295
347
  }
296
348
  ```
297
349
 
350
+ 브라우저 진입점(`@ddunigma/node/browser`)은 `Buffer` API를 노출하지 않습니다.
351
+
352
+ ### Core Entry
353
+
354
+ ```typescript
355
+ class Ddu64 {
356
+ encode(data: string | Uint8Array, options?: DduOptions): string;
357
+ decode(encoded: string, options?: DduOptions): string;
358
+ decodeToUint8Array(encoded: string, options?: DduOptions): Uint8Array;
359
+
360
+ encodeAsync(data: string | Uint8Array, options?: DduOptions): Promise<string>;
361
+ decodeAsync(encoded: string, options?: DduOptions): Promise<string>;
362
+ decodeToUint8ArrayAsync(encoded: string, options?: DduOptions): Promise<Uint8Array>;
363
+
364
+ getStats(data: string | Uint8Array, options?: DduOptions): DduEncodeStats;
365
+ getCharSetInfo(): CharSetInfo;
366
+ }
367
+ ```
368
+
369
+ 코어 진입점(`@ddunigma/node/core`)은 플랫폼 어댑터를 자동 로드하지 않습니다.
370
+ 압축 또는 암호화가 필요한 async 호출에는 `adapter`를 명시적으로 전달하세요.
371
+
298
372
  ## Constructor Options
299
373
 
300
374
  ```typescript
@@ -323,7 +397,7 @@ new Ddu64(dduChar, paddingChar, options?);
323
397
  | `chunkSeparator` | `string` | `"\n"` | 청크 구분자 |
324
398
  | `maxDecodedBytes` | `number` | `67108864` | 디코딩 크기 제한 |
325
399
  | `maxDecompressedBytes` | `number` | `67108864` | 압축해제 크기 제한 |
326
- | `wasmThreshold` | `number` | `4096` | WASM 사용 임계값 |
400
+ | `wasmThreshold` | `number` | `4096` | WASM 사용 임계값 (`Infinity`면 비활성화) |
327
401
  | `throwOnError` | `boolean` | `false` | 초기화 에러 시 throw |
328
402
 
329
403
  ## Per-Call Options
@@ -345,18 +419,24 @@ new Ddu64(dduChar, paddingChar, options?);
345
419
 
346
420
  ## Entry Points
347
421
 
348
- | Import Path | 용도 |
349
- | ------------------------ | ------------------------------------- |
350
- | `@ddunigma/node` | Node.js 전체 기능 (동기+비동기) |
351
- | `@ddunigma/node/browser` | 브라우저 최적화 (Node.js 모듈 미포함) |
352
- | `@ddunigma/node/core` | 최소 코어 (인코딩/디코딩만) |
422
+ | Runtime / Target | Import Path | 용도 |
423
+ | ------------------------------- | ----------------------------------- | ------------------------------------- |
424
+ | Node.js server/CLI | `@ddunigma/node` | Node.js 전체 기능 (동기+비동기) |
425
+ | Browser / Vite / webpack | `@ddunigma/node` 또는 `/browser` | 브라우저 최적화 (BrowserAdapter 기본) |
426
+ | Cloudflare Workers / Deno / Bun | `@ddunigma/node` 또는 `/browser` | Node.js 내장 모듈 없는 Web API 경로 |
427
+ | Adapter 직접 주입 최소 번들 | `@ddunigma/node/core` | 최소 코어 (인코딩/디코딩만) |
428
+
429
+ 루트 진입점은 v4부터 `browser`/`worker`/`workerd`/`deno`/`bun`/`node` 조건을 가진 conditional export입니다. Node.js에서는 기존처럼 `Buffer` API와 NodeAdapter를 노출하고, 브라우저 및 Workers 계열 번들러에서는 Node.js 내장 모듈 없는 BrowserAdapter 경로로 해석됩니다. 런타임 조건을 알 수 없는 ESM 환경의 기본 fallback도 browser 번들을 사용합니다.
430
+ Node.js 런타임에서는 `node` 조건이 `index.js`/`index.cjs`를 선택하므로 기본 import로 NodeAdapter와 `decodeToBuffer()`를 사용할 수 있습니다.
353
431
 
354
432
  ## Build & Test
355
433
 
356
434
  ```bash
357
435
  pnpm test
436
+ pnpm typecheck
358
437
  pnpm build
359
438
  pnpm lint
439
+ pnpm pack:check
360
440
  pnpm bench
361
441
  ```
362
442
 
@@ -0,0 +1,2 @@
1
+ export{a as BrowserAdapter}from'./chunk-P7WJ2LOQ.js';import'./chunk-QR43FNIY.js';//# sourceMappingURL=BrowserAdapter-G4XORUQJ.js.map
2
+ //# sourceMappingURL=BrowserAdapter-G4XORUQJ.js.map
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkRFBXQWSA_cjs=require('./chunk-RFBXQWSA.cjs');require('./chunk-NY4FGVF3.cjs');Object.defineProperty(exports,"BrowserAdapter",{enumerable:true,get:function(){return chunkRFBXQWSA_cjs.a}});//# sourceMappingURL=BrowserAdapter-LIUL744V.cjs.map
2
+ //# sourceMappingURL=BrowserAdapter-LIUL744V.cjs.map
@@ -0,0 +1,2 @@
1
+ export{a as NodeAdapter}from'./chunk-342X2QEY.js';import'./chunk-QR43FNIY.js';//# sourceMappingURL=NodeAdapter-AHALQ4DQ.js.map
2
+ //# sourceMappingURL=NodeAdapter-AHALQ4DQ.js.map
@@ -0,0 +1,2 @@
1
+ 'use strict';var chunkRHVBUC4T_cjs=require('./chunk-RHVBUC4T.cjs');require('./chunk-NY4FGVF3.cjs');Object.defineProperty(exports,"NodeAdapter",{enumerable:true,get:function(){return chunkRHVBUC4T_cjs.a}});//# sourceMappingURL=NodeAdapter-DS44MI5D.cjs.map
2
+ //# sourceMappingURL=NodeAdapter-DS44MI5D.cjs.map
@@ -0,0 +1,203 @@
1
+ import { P as PlatformAdapter, y as KeyDerivationOptions, D as Ddu64Core, u as DduOptions, O as ObfuscationLayer } from './errors-DxOlTuHc.cjs';
2
+
3
+ /**
4
+ * 브라우저 플랫폼 어댑터 구현.
5
+ * 암호화 연산에 Web Crypto API(SubtleCrypto)를 사용하고
6
+ * 압축에 CompressionStream/DecompressionStream을 사용합니다.
7
+ *
8
+ * 이 어댑터는 동기 암호화 또는 압축 연산을 지원하지 않습니다.
9
+ * Brotli는 CompressionStream/DecompressionStream에서 지원되는 런타임에서만 사용할 수 있습니다.
10
+ *
11
+ * @module adapters/BrowserAdapter
12
+ */
13
+
14
+ /**
15
+ * Web API를 사용하여 PlatformAdapter를 구현하는 BrowserAdapter:
16
+ * - AES-256-GCM 및 SHA-256을 위한 Web Crypto API(SubtleCrypto)
17
+ * - 안전한 랜덤 바이트를 위한 crypto.getRandomValues
18
+ * - deflate-raw 압축을 위한 CompressionStream/DecompressionStream
19
+ * - 런타임이 지원하는 경우 Brotli 압축
20
+ */
21
+ declare class BrowserAdapter implements PlatformAdapter {
22
+ readonly supportsSyncCrypto = false;
23
+ readonly supportsSyncCompression = false;
24
+ readonly runtime: "browser" | "edge" | "deno" | "bun";
25
+ constructor(runtime?: "browser" | "edge" | "deno" | "bun");
26
+ get supportsBrotli(): boolean;
27
+ /**
28
+ * UTF-8 키 문자열에서 SHA-256을 통해 256비트 키를 파생합니다.
29
+ * UTF-8 인코딩된 키에 SubtleCrypto.digest('SHA-256', ...)를 사용합니다.
30
+ */
31
+ deriveKey(key: string, options?: KeyDerivationOptions): Promise<Uint8Array>;
32
+ /**
33
+ * 12바이트 IV를 사용하여 AES-256-GCM으로 데이터를 암호화합니다.
34
+ * 와이어 포맷 반환: IV(12바이트) + authTag(16바이트) + 암호문.
35
+ *
36
+ * 참고: Web Crypto는 authTag를 암호문에 추가하므로,
37
+ * 마지막 16바이트를 authTag로 추출하고 와이어 포맷에 맞게 재배치합니다.
38
+ */
39
+ encrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
40
+ /**
41
+ * AES-256-GCM 페이로드를 복호화합니다.
42
+ * 와이어 포맷 기대: IV(12바이트) + authTag(16바이트) + 암호문.
43
+ * 복호화 전에 Web Crypto 형식(암호문 + authTag)으로 재구성합니다.
44
+ */
45
+ decrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
46
+ /**
47
+ * 암호학적으로 안전한 랜덤 바이트를 생성합니다.
48
+ */
49
+ randomBytes(length: number): Uint8Array;
50
+ /**
51
+ * CompressionStream을 통해 deflate로 데이터를 압축합니다.
52
+ * Node.js zlib.deflateRaw와의 상호운용성을 위해 'deflate-raw' 형식만 사용합니다.
53
+ */
54
+ deflate(data: Uint8Array, _level?: number): Promise<Uint8Array>;
55
+ /**
56
+ * DecompressionStream을 통해 deflate 데이터를 압축 해제합니다.
57
+ * Node.js zlib.inflateRaw와의 상호운용성을 위해 'deflate-raw' 형식만 사용합니다.
58
+ * maxBytes가 지정되면 제한을 적용합니다.
59
+ */
60
+ inflate(data: Uint8Array, maxBytes?: number): Promise<Uint8Array>;
61
+ /**
62
+ * CompressionStream을 통해 Brotli로 데이터를 압축합니다.
63
+ * 브라우저 Web API는 Brotli 품질 레벨을 받지 않으므로 level 값은 무시됩니다.
64
+ */
65
+ brotliCompress(data: Uint8Array, _level?: number): Promise<Uint8Array>;
66
+ /**
67
+ * DecompressionStream을 통해 Brotli 데이터를 압축 해제합니다.
68
+ */
69
+ brotliDecompress(data: Uint8Array, maxBytes?: number): Promise<Uint8Array>;
70
+ /**
71
+ * CompressionStream에 적합한 deflate 형식을 결정합니다.
72
+ * Node.js zlib.deflateRaw와의 상호운용성을 위해 'deflate-raw'만 사용합니다.
73
+ */
74
+ private getDeflateFormat;
75
+ private writeAndReadStream;
76
+ private readAllChunks;
77
+ }
78
+
79
+ /**
80
+ * Runtime detection helpers with no platform-specific imports.
81
+ *
82
+ * @module adapters/runtime
83
+ */
84
+ /** 감지된 런타임 환경 식별자 */
85
+ type RuntimeId = "node" | "browser" | "edge" | "deno" | "bun" | "unknown";
86
+ /**
87
+ * 현재 JavaScript 런타임 환경을 감지합니다.
88
+ *
89
+ * 감지는 순수하게 globalThis 검사에 기반하며 Node.js 내장 모듈을 임포트하지 않습니다.
90
+ */
91
+ declare function detectRuntime(): RuntimeId;
92
+
93
+ /**
94
+ * ddunigma Web Streams API 구현.
95
+ *
96
+ * Web Streams API(globalThis.TransformStream)를 사용하는
97
+ * TransformStream 기반 인코딩/디코딩 파이프라인을 제공합니다.
98
+ * 모든 최신 브라우저와 Node.js에서 사용 가능합니다.
99
+ *
100
+ * 스트리밍 모드:
101
+ * - 인코딩: 압축/암호화/체크섬 비활성화 + 2의 제곱수 charset에서 청크 단위 출력
102
+ * - 디코딩: footer의 압축/암호화 마커를 최종 신뢰하기 위해 payload를 축적 후 처리
103
+ *
104
+ * 스트림 헤더 형식: [pad]DDS1[D|B|N][1|0][pad]
105
+ * D=deflate, B=brotli, N=없음 (압축), 1/0 (암호화).
106
+ *
107
+ * @module streams/WebStreams
108
+ */
109
+
110
+ /**
111
+ * 바이너리 데이터를 charset 인코딩 문자열로 변환하는
112
+ * Web Streams API TransformStream을 생성합니다.
113
+ *
114
+ * 압축/암호화/체크섬이 비활성화되고 charset이 2의 제곱수일 때 각 청크를 즉시 인코딩합니다.
115
+ * 그 외에는 전체 데이터를 축적한 후 flush에서 처리합니다.
116
+ *
117
+ * @param encoder - 인코딩에 사용할 Ddu64Core 인스턴스
118
+ * @param options - 인코딩 옵션 (compress, encrypt, compressionAlgorithm 등)
119
+ * @returns TransformStream<Uint8Array, string>
120
+ */
121
+ declare function createReadableEncodeStream(encoder: Ddu64Core, options?: DduOptions): TransformStream<Uint8Array, string>;
122
+ /**
123
+ * charset 인코딩 문자열을 바이너리 데이터로 역변환하는
124
+ * Web Streams API TransformStream을 생성합니다.
125
+ *
126
+ * 스트림은 DDS1 스트림 헤더를 조기 검증하되, 헤더만으로 복호화/압축해제를 비활성화하지 않습니다.
127
+ * footer가 최종 wire metadata이므로 전체 페이로드를 축적 후 일괄 디코딩합니다.
128
+ *
129
+ * @param encoder - 디코딩에 사용할 Ddu64Core 인스턴스
130
+ * @param options - 디코딩 옵션
131
+ * @returns TransformStream<string, Uint8Array>
132
+ */
133
+ declare function createReadableDecodeStream(encoder: Ddu64Core, options?: DduOptions): TransformStream<string, Uint8Array>;
134
+
135
+ /**
136
+ * 한글 음절 난독화 레이어 구현.
137
+ *
138
+ * 암호화된 charset 인코딩 문자열을 결정론적 전단사 매핑을 사용하여
139
+ * 자연스러운 한국어 음절 블록으로 변환합니다. 매핑은 다음을 보장합니다:
140
+ * - 모든 출력 문자가 유효한 한국어 음절 블록 (U+AC00–U+D7A3)
141
+ * - 단일 문자 빈도가 기대 균등 빈도의 3배를 초과하지 않음
142
+ * - 출력 길이 <= 입력 길이의 1.5배 (실제로는 1:1 매핑)
143
+ *
144
+ * 플랫폼 독립적: Node.js 임포트 없음.
145
+ *
146
+ * @module obfuscation/ObfuscationLayer
147
+ */
148
+
149
+ /**
150
+ * 한글 음절 매핑을 사용하여 ObfuscationLayer 인터페이스를 구현합니다.
151
+ *
152
+ * 입력 알파벳(인코더가 사용하는 charset 문자)이 주어지면,
153
+ * 이 레이어는 각 문자를 결정론적으로 한글 음절에 매핑합니다.
154
+ * 매핑은 전단사(가역적)이며 위치에 따라 각 문자의 할당된 음절 범위를
155
+ * 순환하여 출력 빈도를 균등하게 분배합니다.
156
+ */
157
+ declare class HangulObfuscationLayer implements ObfuscationLayer {
158
+ private readonly config;
159
+ /**
160
+ * 새 HangulObfuscationLayer를 생성합니다.
161
+ *
162
+ * @param alphabet - 완전한 입력 알파벳 (charset 문자 + 패딩 문자).
163
+ * 인코딩된 문자열에 나타날 수 있는 모든 고유 문자.
164
+ */
165
+ constructor(alphabet: string[]);
166
+ /**
167
+ * 암호화된 charset 인코딩 문자열을 한글 음절로 변환합니다.
168
+ *
169
+ * 각 입력 문자는 할당된 범위의 한글 음절에 매핑됩니다.
170
+ * 문자열 내 위치가 범위 내 어떤 음절을 사용할지 결정하여
171
+ * 균등한 빈도 분포를 보장합니다.
172
+ *
173
+ * @param input - 암호화된 charset 인코딩 문자열
174
+ * @returns 한글 음절 블록 문자열 (U+AC00–U+D7A3)
175
+ * @throws 입력에 알파벳에 없는 문자가 포함된 경우 에러
176
+ */
177
+ obfuscate(input: string): string;
178
+ /**
179
+ * 난독화를 역변환하여 원본 charset 인코딩 문자열을 복원합니다.
180
+ *
181
+ * 각 한글 음절이 어떤 문자의 범위에 속하는지 판별하여
182
+ * 원래 문자로 매핑합니다.
183
+ *
184
+ * @param input - 난독화된 한글 음절 문자열
185
+ * @returns 원본 charset 인코딩 문자열
186
+ * @throws 입력에 유효한 한글 음절 범위 밖의 문자가 포함되거나
187
+ * 알파벳 문자에 매핑되지 않는 문자가 포함된 경우 에러
188
+ */
189
+ deobfuscate(input: string): string;
190
+ }
191
+ /**
192
+ * 주어진 charset 설정에 대한 ObfuscationLayer를 생성합니다.
193
+ *
194
+ * charset 문자와 패딩 문자로부터 완전한 알파벳을 구성한 후
195
+ * 한글 난독화 레이어를 생성합니다.
196
+ *
197
+ * @param charSet - 인코딩에 사용되는 charset 문자
198
+ * @param paddingChar - 패딩 문자
199
+ * @returns ObfuscationLayer 인스턴스
200
+ */
201
+ declare function createObfuscationLayer(charSet: string[], paddingChar: string): ObfuscationLayer;
202
+
203
+ export { BrowserAdapter as B, HangulObfuscationLayer as H, createReadableDecodeStream as a, createReadableEncodeStream as b, createObfuscationLayer as c, detectRuntime as d };
@@ -0,0 +1,203 @@
1
+ import { P as PlatformAdapter, y as KeyDerivationOptions, D as Ddu64Core, u as DduOptions, O as ObfuscationLayer } from './errors-DxOlTuHc.js';
2
+
3
+ /**
4
+ * 브라우저 플랫폼 어댑터 구현.
5
+ * 암호화 연산에 Web Crypto API(SubtleCrypto)를 사용하고
6
+ * 압축에 CompressionStream/DecompressionStream을 사용합니다.
7
+ *
8
+ * 이 어댑터는 동기 암호화 또는 압축 연산을 지원하지 않습니다.
9
+ * Brotli는 CompressionStream/DecompressionStream에서 지원되는 런타임에서만 사용할 수 있습니다.
10
+ *
11
+ * @module adapters/BrowserAdapter
12
+ */
13
+
14
+ /**
15
+ * Web API를 사용하여 PlatformAdapter를 구현하는 BrowserAdapter:
16
+ * - AES-256-GCM 및 SHA-256을 위한 Web Crypto API(SubtleCrypto)
17
+ * - 안전한 랜덤 바이트를 위한 crypto.getRandomValues
18
+ * - deflate-raw 압축을 위한 CompressionStream/DecompressionStream
19
+ * - 런타임이 지원하는 경우 Brotli 압축
20
+ */
21
+ declare class BrowserAdapter implements PlatformAdapter {
22
+ readonly supportsSyncCrypto = false;
23
+ readonly supportsSyncCompression = false;
24
+ readonly runtime: "browser" | "edge" | "deno" | "bun";
25
+ constructor(runtime?: "browser" | "edge" | "deno" | "bun");
26
+ get supportsBrotli(): boolean;
27
+ /**
28
+ * UTF-8 키 문자열에서 SHA-256을 통해 256비트 키를 파생합니다.
29
+ * UTF-8 인코딩된 키에 SubtleCrypto.digest('SHA-256', ...)를 사용합니다.
30
+ */
31
+ deriveKey(key: string, options?: KeyDerivationOptions): Promise<Uint8Array>;
32
+ /**
33
+ * 12바이트 IV를 사용하여 AES-256-GCM으로 데이터를 암호화합니다.
34
+ * 와이어 포맷 반환: IV(12바이트) + authTag(16바이트) + 암호문.
35
+ *
36
+ * 참고: Web Crypto는 authTag를 암호문에 추가하므로,
37
+ * 마지막 16바이트를 authTag로 추출하고 와이어 포맷에 맞게 재배치합니다.
38
+ */
39
+ encrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
40
+ /**
41
+ * AES-256-GCM 페이로드를 복호화합니다.
42
+ * 와이어 포맷 기대: IV(12바이트) + authTag(16바이트) + 암호문.
43
+ * 복호화 전에 Web Crypto 형식(암호문 + authTag)으로 재구성합니다.
44
+ */
45
+ decrypt(data: Uint8Array, keyHash: Uint8Array, aad?: Uint8Array): Promise<Uint8Array>;
46
+ /**
47
+ * 암호학적으로 안전한 랜덤 바이트를 생성합니다.
48
+ */
49
+ randomBytes(length: number): Uint8Array;
50
+ /**
51
+ * CompressionStream을 통해 deflate로 데이터를 압축합니다.
52
+ * Node.js zlib.deflateRaw와의 상호운용성을 위해 'deflate-raw' 형식만 사용합니다.
53
+ */
54
+ deflate(data: Uint8Array, _level?: number): Promise<Uint8Array>;
55
+ /**
56
+ * DecompressionStream을 통해 deflate 데이터를 압축 해제합니다.
57
+ * Node.js zlib.inflateRaw와의 상호운용성을 위해 'deflate-raw' 형식만 사용합니다.
58
+ * maxBytes가 지정되면 제한을 적용합니다.
59
+ */
60
+ inflate(data: Uint8Array, maxBytes?: number): Promise<Uint8Array>;
61
+ /**
62
+ * CompressionStream을 통해 Brotli로 데이터를 압축합니다.
63
+ * 브라우저 Web API는 Brotli 품질 레벨을 받지 않으므로 level 값은 무시됩니다.
64
+ */
65
+ brotliCompress(data: Uint8Array, _level?: number): Promise<Uint8Array>;
66
+ /**
67
+ * DecompressionStream을 통해 Brotli 데이터를 압축 해제합니다.
68
+ */
69
+ brotliDecompress(data: Uint8Array, maxBytes?: number): Promise<Uint8Array>;
70
+ /**
71
+ * CompressionStream에 적합한 deflate 형식을 결정합니다.
72
+ * Node.js zlib.deflateRaw와의 상호운용성을 위해 'deflate-raw'만 사용합니다.
73
+ */
74
+ private getDeflateFormat;
75
+ private writeAndReadStream;
76
+ private readAllChunks;
77
+ }
78
+
79
+ /**
80
+ * Runtime detection helpers with no platform-specific imports.
81
+ *
82
+ * @module adapters/runtime
83
+ */
84
+ /** 감지된 런타임 환경 식별자 */
85
+ type RuntimeId = "node" | "browser" | "edge" | "deno" | "bun" | "unknown";
86
+ /**
87
+ * 현재 JavaScript 런타임 환경을 감지합니다.
88
+ *
89
+ * 감지는 순수하게 globalThis 검사에 기반하며 Node.js 내장 모듈을 임포트하지 않습니다.
90
+ */
91
+ declare function detectRuntime(): RuntimeId;
92
+
93
+ /**
94
+ * ddunigma Web Streams API 구현.
95
+ *
96
+ * Web Streams API(globalThis.TransformStream)를 사용하는
97
+ * TransformStream 기반 인코딩/디코딩 파이프라인을 제공합니다.
98
+ * 모든 최신 브라우저와 Node.js에서 사용 가능합니다.
99
+ *
100
+ * 스트리밍 모드:
101
+ * - 인코딩: 압축/암호화/체크섬 비활성화 + 2의 제곱수 charset에서 청크 단위 출력
102
+ * - 디코딩: footer의 압축/암호화 마커를 최종 신뢰하기 위해 payload를 축적 후 처리
103
+ *
104
+ * 스트림 헤더 형식: [pad]DDS1[D|B|N][1|0][pad]
105
+ * D=deflate, B=brotli, N=없음 (압축), 1/0 (암호화).
106
+ *
107
+ * @module streams/WebStreams
108
+ */
109
+
110
+ /**
111
+ * 바이너리 데이터를 charset 인코딩 문자열로 변환하는
112
+ * Web Streams API TransformStream을 생성합니다.
113
+ *
114
+ * 압축/암호화/체크섬이 비활성화되고 charset이 2의 제곱수일 때 각 청크를 즉시 인코딩합니다.
115
+ * 그 외에는 전체 데이터를 축적한 후 flush에서 처리합니다.
116
+ *
117
+ * @param encoder - 인코딩에 사용할 Ddu64Core 인스턴스
118
+ * @param options - 인코딩 옵션 (compress, encrypt, compressionAlgorithm 등)
119
+ * @returns TransformStream<Uint8Array, string>
120
+ */
121
+ declare function createReadableEncodeStream(encoder: Ddu64Core, options?: DduOptions): TransformStream<Uint8Array, string>;
122
+ /**
123
+ * charset 인코딩 문자열을 바이너리 데이터로 역변환하는
124
+ * Web Streams API TransformStream을 생성합니다.
125
+ *
126
+ * 스트림은 DDS1 스트림 헤더를 조기 검증하되, 헤더만으로 복호화/압축해제를 비활성화하지 않습니다.
127
+ * footer가 최종 wire metadata이므로 전체 페이로드를 축적 후 일괄 디코딩합니다.
128
+ *
129
+ * @param encoder - 디코딩에 사용할 Ddu64Core 인스턴스
130
+ * @param options - 디코딩 옵션
131
+ * @returns TransformStream<string, Uint8Array>
132
+ */
133
+ declare function createReadableDecodeStream(encoder: Ddu64Core, options?: DduOptions): TransformStream<string, Uint8Array>;
134
+
135
+ /**
136
+ * 한글 음절 난독화 레이어 구현.
137
+ *
138
+ * 암호화된 charset 인코딩 문자열을 결정론적 전단사 매핑을 사용하여
139
+ * 자연스러운 한국어 음절 블록으로 변환합니다. 매핑은 다음을 보장합니다:
140
+ * - 모든 출력 문자가 유효한 한국어 음절 블록 (U+AC00–U+D7A3)
141
+ * - 단일 문자 빈도가 기대 균등 빈도의 3배를 초과하지 않음
142
+ * - 출력 길이 <= 입력 길이의 1.5배 (실제로는 1:1 매핑)
143
+ *
144
+ * 플랫폼 독립적: Node.js 임포트 없음.
145
+ *
146
+ * @module obfuscation/ObfuscationLayer
147
+ */
148
+
149
+ /**
150
+ * 한글 음절 매핑을 사용하여 ObfuscationLayer 인터페이스를 구현합니다.
151
+ *
152
+ * 입력 알파벳(인코더가 사용하는 charset 문자)이 주어지면,
153
+ * 이 레이어는 각 문자를 결정론적으로 한글 음절에 매핑합니다.
154
+ * 매핑은 전단사(가역적)이며 위치에 따라 각 문자의 할당된 음절 범위를
155
+ * 순환하여 출력 빈도를 균등하게 분배합니다.
156
+ */
157
+ declare class HangulObfuscationLayer implements ObfuscationLayer {
158
+ private readonly config;
159
+ /**
160
+ * 새 HangulObfuscationLayer를 생성합니다.
161
+ *
162
+ * @param alphabet - 완전한 입력 알파벳 (charset 문자 + 패딩 문자).
163
+ * 인코딩된 문자열에 나타날 수 있는 모든 고유 문자.
164
+ */
165
+ constructor(alphabet: string[]);
166
+ /**
167
+ * 암호화된 charset 인코딩 문자열을 한글 음절로 변환합니다.
168
+ *
169
+ * 각 입력 문자는 할당된 범위의 한글 음절에 매핑됩니다.
170
+ * 문자열 내 위치가 범위 내 어떤 음절을 사용할지 결정하여
171
+ * 균등한 빈도 분포를 보장합니다.
172
+ *
173
+ * @param input - 암호화된 charset 인코딩 문자열
174
+ * @returns 한글 음절 블록 문자열 (U+AC00–U+D7A3)
175
+ * @throws 입력에 알파벳에 없는 문자가 포함된 경우 에러
176
+ */
177
+ obfuscate(input: string): string;
178
+ /**
179
+ * 난독화를 역변환하여 원본 charset 인코딩 문자열을 복원합니다.
180
+ *
181
+ * 각 한글 음절이 어떤 문자의 범위에 속하는지 판별하여
182
+ * 원래 문자로 매핑합니다.
183
+ *
184
+ * @param input - 난독화된 한글 음절 문자열
185
+ * @returns 원본 charset 인코딩 문자열
186
+ * @throws 입력에 유효한 한글 음절 범위 밖의 문자가 포함되거나
187
+ * 알파벳 문자에 매핑되지 않는 문자가 포함된 경우 에러
188
+ */
189
+ deobfuscate(input: string): string;
190
+ }
191
+ /**
192
+ * 주어진 charset 설정에 대한 ObfuscationLayer를 생성합니다.
193
+ *
194
+ * charset 문자와 패딩 문자로부터 완전한 알파벳을 구성한 후
195
+ * 한글 난독화 레이어를 생성합니다.
196
+ *
197
+ * @param charSet - 인코딩에 사용되는 charset 문자
198
+ * @param paddingChar - 패딩 문자
199
+ * @returns ObfuscationLayer 인스턴스
200
+ */
201
+ declare function createObfuscationLayer(charSet: string[], paddingChar: string): ObfuscationLayer;
202
+
203
+ export { BrowserAdapter as B, HangulObfuscationLayer as H, createReadableDecodeStream as a, createReadableEncodeStream as b, createObfuscationLayer as c, detectRuntime as d };