@ddunigma/node 2.2.0 → 3.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
@@ -1,18 +1,12 @@
1
- ## ddunigma Node
1
+ # ddunigma Node
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/@ddunigma%2Fnode.svg)](https://www.npmjs.com/package/@ddunigma/node)
4
4
 
5
- ## Overview
6
-
7
- Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python original)
8
-
9
5
  커스텀 charset을 사용하는 Base64 스타일 인코더/디코더 라이브러리입니다.
10
6
 
11
- ## Documents
7
+ V2 추가사항
12
8
 
13
- - `README.md`: 설치, 사용법, 공개 API 요약
14
- - `CHANGELOG.md`: 공개 변경 이력
15
- - `RELEASE.md`: 배포 체크리스트와 릴리즈 기준
9
+ - 이제 한글 종성 결합 시스템을 활용하여 8개 기본 문자 × 8개 종성으로 64가지 조합을 만들어, 6비트를 한 글자로 표현합니다.
16
10
 
17
11
  ### Credits
18
12
 
@@ -24,7 +18,6 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
24
18
  ## Requirements
25
19
 
26
20
  - **Node.js >= 18.0.0**
27
- - 라이브러리는 `ES2022` 타깃으로 빌드되며, 현재 스트림 암호화/압축 조합은 Node 18+ 기준으로 검증됩니다.
28
21
 
29
22
  ## Install
30
23
 
@@ -32,223 +25,195 @@ Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python o
32
25
  npm install @ddunigma/node
33
26
  ```
34
27
 
35
- ## Usage
36
-
37
- ### 기본 인코딩/디코딩
28
+ ## Quick Start
38
29
 
39
30
  ```typescript
40
- import { Ddu64 } from "@ddunigma/node";
41
-
42
- // 커스텀 charset으로 인코더 생성
43
- const encoder = new Ddu64("우따야", "뭐");
31
+ import { Ddu64, DduSetSymbol } from "@ddunigma/node";
44
32
 
45
- const text = "Hello World!";
46
- const encoded = encoder.encode(text);
47
- console.log(encoded); // 우따야뭐우따... (인코딩된 문자열)
33
+ // V2 (기본, 한글 종성 결합 64개)
34
+ const ddu = new Ddu64();
35
+ ddu.encode("안녕하세요"); // "뎯땩잇땨뎪뎨잇잉뎯욱잇우뎯땨읶뎨뎯땩듂잊"
36
+ ddu.decode("뎯땩잇땨뎪뎨잇잉뎯욱잇우뎯땨읶뎨뎯땩듂잊"); // "안녕하세요"
48
37
 
49
- const decoded = encoder.decode(encoded);
50
- console.log(decoded); // "Hello World!"
38
+ // V1 (구버전 호환, 8개 문자 쌍 방식)
39
+ const dduV1 = new Ddu64(undefined, undefined, { dduSetSymbol: DduSetSymbol.DDU_V1 });
40
+ dduV1.encode("안녕하세요"); // ".우땨땨이?땨뜌.이.뜌이?이!.우우땨이?우뜌.우땨뜌이이.뜌.우땨땨!이이야"
41
+ dduV1.decode(".우땨땨이?땨뜌.이.뜌이?이!.우우땨이?우뜌.우땨뜌이이.뜌.우땨땨!이이야"); // "안녕하세요"
51
42
  ```
52
43
 
53
- ### 미리 정의된 Charset 사용
44
+ ---
45
+
46
+ ## 기본 사용법
47
+
48
+ ### 인코딩/디코딩
54
49
 
55
50
  ```typescript
56
- import { Ddu64, DduSetSymbol } from "@ddunigma/node";
51
+ import { Ddu64 } from "@ddunigma/node";
57
52
 
58
- // ONECHARSET (64개 문자)
59
- const encoder1 = new Ddu64(undefined, undefined, {
60
- dduSetSymbol: DduSetSymbol.ONECHARSET,
61
- });
53
+ const encoder = new Ddu64();
62
54
 
63
- // DDU (8개 문자)
64
- const encoder2 = new Ddu64(undefined, undefined, {
65
- dduSetSymbol: DduSetSymbol.DDU,
66
- });
55
+ const encoded = encoder.encode("Hello World!");
56
+ const decoded = encoder.decode(encoded);
57
+ ```
67
58
 
68
- // TWOCHARSET (1024개 문자)
69
- const encoder3 = new Ddu64(undefined, undefined, {
70
- dduSetSymbol: DduSetSymbol.TWOCHARSET,
71
- });
59
+ ### 커스텀 charset
72
60
 
73
- // THREECHARSET (32768개 문자)
74
- const encoder4 = new Ddu64(undefined, undefined, {
75
- dduSetSymbol: DduSetSymbol.THREECHARSET,
76
- });
61
+ ```typescript
62
+ // 문자열 또는 배열로 charset 지정
63
+ const encoder = new Ddu64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=");
77
64
 
78
- const text = "안녕하세요";
79
- const encoded = encoder1.encode(text);
80
- const decoded = encoder1.decode(encoded);
65
+ // 종성 결합 커스텀 charset (dduChar × codaChar 동적 생성)
66
+ const encoder2 = new Ddu64(["가", "나", "다", "라"], "뭐", {
67
+ codaChar: ["", "ㄱ", "ㄲ", "ㄷ"], // 4×4 = 16개 조합
68
+ });
81
69
  ```
82
70
 
83
- ### 압축 인코딩
71
+ ### 프리셋
72
+
73
+ | Symbol | 문자 수 | 비트 | 설명 |
74
+ | ------------ | ------- | ---- | ------------------------------------ |
75
+ | `DDU` | 64 | 6 | 한글 종성 결합 (8 기본문자 × 8 종성) |
76
+ | `DDU_V1` | 8 | 3 | 구버전 호환 (뜌땨이우야!?.) |
77
+ | `ONECHARSET` | 64 | 6 | 영문 + 숫자 + 특수문자 |
84
78
 
85
79
  ```typescript
86
- import { Ddu64 } from "@ddunigma/node";
80
+ import { Ddu64, DduSetSymbol } from "@ddunigma/node";
87
81
 
88
- // 생성자에서 기본 압축 활성화
89
82
  const encoder = new Ddu64(undefined, undefined, {
90
- compress: true,
83
+ dduSetSymbol: DduSetSymbol.ONECHARSET,
91
84
  });
92
-
93
- // 또는 encode 호출 시 압축 옵션 지정
94
- const text = "반복되는 긴 텍스트...".repeat(100);
95
- const encoded = encoder.encode(text, { compress: true });
96
- const decoded = encoder.decode(encoded); // 자동으로 압축 해제
97
85
  ```
98
86
 
99
- ### URL-Safe 인코딩
87
+ ---
88
+
89
+ ## 고급 기능
90
+
91
+ ### 압축
92
+
93
+ deflate(기본) 또는 brotli 압축을 지원합니다. 디코딩 시 자동으로 압축 여부를 감지합니다.
100
94
 
101
95
  ```typescript
102
- import { CharsetBuilder, Ddu64 } from "@ddunigma/node";
96
+ const encoder = new Ddu64();
103
97
 
104
- const { charset, padding } = CharsetBuilder.base64().buildWithPadding("=");
98
+ // 호출 옵션으로 지정
99
+ const encoded = encoder.encode(longText, { compress: true });
100
+ const decoded = encoder.decode(encoded);
105
101
 
106
- const encoder = new Ddu64(charset, padding, {
107
- urlSafe: true, // +, /, = URL 안전 문자로 변환
102
+ // 생성자에서 기본 활성화
103
+ const compressEncoder = new Ddu64(undefined, undefined, {
104
+ compress: true,
105
+ compressionAlgorithm: "brotli",
106
+ compressionLevel: 6,
108
107
  });
109
-
110
- const encoded = encoder.encode("Hello World!");
111
- // URL에서 안전하게 사용 가능한 문자열 반환
112
108
  ```
113
109
 
114
- `urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 활성화됩니다. 또한 chunk 정규화를 위해 custom charset/padding에는 `\r`, `\n` 을 사용할 수 없습니다.
110
+ ### 암호화
115
111
 
116
- ### 체크섬 (무결성 검증)
112
+ AES-256-GCM 암호화를 내장합니다. 동일한 키로 생성된 인코더만 복호화할 수 있습니다.
117
113
 
118
114
  ```typescript
119
- import { Ddu64 } from "@ddunigma/node";
120
-
121
115
  const encoder = new Ddu64(undefined, undefined, {
122
- checksum: true, // CRC32 체크섬 활성화
116
+ encryptionKey: "my-secret-key",
123
117
  });
124
118
 
125
- const encoded = encoder.encode("Important data", { checksum: true });
126
- const decoded = encoder.decode(encoded); // 자동으로 체크섬 검증
127
- // 체크섬 불일치 시 에러 발생
119
+ const encoded = encoder.encode("비밀 메시지");
120
+ const decoded = encoder.decode(encoded);
128
121
  ```
129
122
 
130
- ### 암호화
123
+ ### 체크섬
124
+
125
+ CRC32 체크섬으로 데이터 무결성을 검증합니다.
131
126
 
132
127
  ```typescript
133
- import { Ddu64 } from "@ddunigma/node";
128
+ const encoder = new Ddu64();
134
129
 
135
- const encoder = new Ddu64(undefined, undefined, {
136
- encryptionKey: "my-secret-key-123", // AES-256-GCM 암호화
137
- });
130
+ const encoded = encoder.encode(data, { checksum: true });
131
+ const decoded = encoder.decode(encoded, { checksum: true });
132
+ // 데이터 변조 시 에러 발생
133
+ ```
134
+
135
+ ### URL-Safe
138
136
 
139
- const encoded = encoder.encode("Secret message!");
140
- const decoded = encoder.decode(encoded); // 자동으로 복호화
137
+ `+`, `/`, `=` 를 URL 안전 문자(`-`, `_`, `.`)로 변환합니다.
138
+
139
+ ```typescript
140
+ const encoder = new Ddu64("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/", "=", {
141
+ urlSafe: true,
142
+ });
141
143
  ```
142
144
 
145
+ > charset/padding에 `-`, `_`, `.` 가 포함되면 urlSafe를 활성화할 수 없습니다.
146
+
143
147
  ### 청크 분할
144
148
 
145
149
  ```typescript
146
- import { Ddu64 } from "@ddunigma/node";
147
-
148
150
  const encoder = new Ddu64();
149
151
 
150
- const encoded = encoder.encode(longData, {
151
- chunkSize: 76, // 76자마다 분할
152
- chunkSeparator: "\n", // 줄바꿈으로 구분
152
+ const encoded = encoder.encode(data, {
153
+ chunkSize: 76,
154
+ chunkSeparator: "\n",
153
155
  });
154
- // 결과: "ABCDxyz...\nEFGHijk...\n..."
155
-
156
- const decoded = encoder.decode(encoded); // 자동으로 줄바꿈 제거
156
+ // 디코딩 시 구분자 자동 제거
157
157
  ```
158
158
 
159
- ### 비동기 인코딩/디코딩
159
+ ### 비동기 처리
160
160
 
161
- ```typescript
162
- import { Ddu64 } from "@ddunigma/node";
163
-
164
- const encoder = new Ddu64();
161
+ 대용량 데이터에서 이벤트 루프 블로킹을 방지합니다.
165
162
 
166
- // 비동기 인코딩
167
- const encoded = await encoder.encodeAsync(largeData);
163
+ ```typescript
164
+ const encoded = await encoder.encodeAsync(largeBuffer);
168
165
  const decoded = await encoder.decodeAsync(encoded);
169
166
  const buffer = await encoder.decodeToBufferAsync(encoded);
170
167
  ```
171
168
 
172
- 큰 입력에서 기본 경로는 이벤트 루프에 양보하면서 처리합니다. 다만 압축, 암호화, 체크섬, URL-safe 같은 옵션이 함께 켜진 복합 경로는 안전성을 위해 전체 payload 기준 fallback을 사용할 수 있습니다.
173
-
174
169
  ### 진행률 콜백
175
170
 
176
171
  ```typescript
177
- import { Ddu64 } from "@ddunigma/node";
178
-
179
- const encoder = new Ddu64();
180
-
181
- encoder.encode(largeData, {
182
- onProgress: (info) => {
183
- console.log(`진행률: ${info.percent}%`);
184
- console.log(`처리됨: ${info.processedBytes}/${info.totalBytes}`);
172
+ encoder.encode(data, {
173
+ onProgress: ({ percent, stage }) => {
174
+ console.log(`${percent}% (${stage})`);
185
175
  },
186
176
  });
187
177
  ```
188
178
 
189
- ### 통계/분석
179
+ ### 통계
190
180
 
191
181
  ```typescript
192
- import { Ddu64 } from "@ddunigma/node";
193
-
194
- const encoder = new Ddu64();
195
-
196
- const stats = encoder.getStats("Test data", { compress: true });
197
- console.log(stats);
198
- // {
199
- // originalSize: 9,
200
- // encodedSize: 12,
201
- // compressedSize: 17,
202
- // compressionRatio: 1.89,
203
- // expansionRatio: 1.33,
204
- // charsetSize: 64,
205
- // bitLength: 6
206
- // }
182
+ const stats = encoder.getStats(data, { compress: true });
183
+ // { originalSize, encodedSize, compressedSize, compressionRatio, expansionRatio, charsetSize, bitLength }
207
184
  ```
208
185
 
209
186
  ### Zip Bomb 방어
210
187
 
211
188
  ```typescript
212
- import { Ddu64 } from "@ddunigma/node";
213
-
214
189
  const encoder = new Ddu64(undefined, undefined, {
215
190
  maxDecodedBytes: 10 * 1024 * 1024, // 10MB
216
191
  maxDecompressedBytes: 50 * 1024 * 1024, // 50MB
217
192
  });
218
-
219
- // 제한 초과 시 에러 발생
220
193
  ```
221
194
 
222
195
  ---
223
196
 
224
197
  ## CharsetBuilder
225
198
 
226
- 커스텀 charset을 쉽게 생성할 수 있는 빌더 유틸리티입니다.
199
+ 커스텀 charset을 빌더 패턴으로 생성합니다.
227
200
 
228
201
  ```typescript
229
202
  import { CharsetBuilder } from "@ddunigma/node";
230
203
 
231
- // 유니코드 범위에서 생성
232
- const chars1 = CharsetBuilder.fromUnicodeRange(0x4e00, 0x4e3f).build();
204
+ // 유니코드 범위
205
+ CharsetBuilder.fromUnicodeRange(0x4e00, 0x4e3f).build();
233
206
 
234
- // Base64 문자셋
235
- const chars2 = CharsetBuilder.base64().build();
207
+ // Base64에서 혼동 문자 제외
208
+ CharsetBuilder.base64().excludeConfusing().build();
236
209
 
237
- // 혼동 문자 제외 (0, O, 1, l, I 등)
238
- const chars3 = CharsetBuilder.base64().excludeConfusing().build();
239
-
240
- // 2의 제곱수로 제한
241
- const chars4 = CharsetBuilder.fromString("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
210
+ // 2의 제곱수로 제한 + 시드 셔플
211
+ CharsetBuilder.fromString("ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
242
212
  .limitToPowerOfTwo()
243
- .build(); // 32자
244
-
245
- // URL 안전 문자만
246
- const chars5 = CharsetBuilder.base64().excludeUrlUnsafe().build();
247
-
248
- // 시드 기반 셔플
249
- const chars6 = CharsetBuilder.base64().shuffle(12345).build();
213
+ .shuffle(12345)
214
+ .build();
250
215
 
251
- // 패딩 문자와 함께 빌드
216
+ // 패딩 문자 자동 선택
252
217
  const { charset, padding } = CharsetBuilder.base64().buildWithPadding();
253
218
  ```
254
219
 
@@ -256,226 +221,127 @@ const { charset, padding } = CharsetBuilder.base64().buildWithPadding();
256
221
 
257
222
  ## DduPipeline
258
223
 
259
- 다단계 인코딩/암호화/압축을 조합할 있는 파이프라인 빌더입니다.
224
+ 압축 암호화 인코딩을 체이닝하고, `reverse()`로 역순 복원합니다.
260
225
 
261
226
  ```typescript
262
227
  import { DduPipeline, Ddu64 } from "@ddunigma/node";
263
228
 
264
- const encoder = new Ddu64();
265
-
266
- // 압축 → 암호화 → 인코딩 파이프라인
267
- const pipeline = new DduPipeline()
268
- .compress(6, "brotli")
269
- .encrypt("my-secret-key")
270
- .encode(encoder);
229
+ const pipeline = new DduPipeline().compress(6, "brotli").encrypt("secret-key").encode(new Ddu64());
271
230
 
272
- const encoded = pipeline.processToString("Hello World!");
273
-
274
- // 역순 파이프라인으로 복원
231
+ const encoded = pipeline.processToString("Hello");
275
232
  const decoded = pipeline.reverse().processToString(encoded);
276
233
  ```
277
234
 
278
235
  ---
279
236
 
280
- ## 스트림 지원
237
+ ## 스트림
281
238
 
282
- 대용량 파일 처리를 위한 스트림 인코딩/디코딩을 지원합니다.
239
+ 대용량 파일을 메모리 효율적으로 처리합니다. 스트림 헤더로 압축/암호화를 자동 감지합니다.
283
240
 
284
241
  ```typescript
285
242
  import { Ddu64, createEncodeStream, createDecodeStream } from "@ddunigma/node";
286
243
  import fs from "fs";
287
244
 
288
- const encoder = new Ddu64();
289
-
290
- // 인코딩 스트림
291
- fs.createReadStream("input.bin")
292
- .pipe(createEncodeStream(encoder))
293
- .pipe(fs.createWriteStream("output.txt"));
294
-
295
- // 디코딩 스트림
296
- fs.createReadStream("output.txt")
297
- .pipe(createDecodeStream(encoder))
298
- .pipe(fs.createWriteStream("restored.bin"));
299
- ```
300
-
301
- 압축과 암호화를 함께 사용하는 스트림도 바로 연결할 수 있습니다.
302
-
303
- ```typescript
304
- import { Ddu64, DduSetSymbol, createEncodeStream, createDecodeStream } from "@ddunigma/node";
305
- import fs from "fs";
306
-
307
245
  const encoder = new Ddu64(undefined, undefined, {
308
- dduSetSymbol: DduSetSymbol.ONECHARSET,
309
246
  compress: true,
310
- compressionAlgorithm: "brotli",
311
- encryptionKey: "stream-secret-key",
247
+ encryptionKey: "stream-key",
312
248
  });
313
249
 
314
- fs.createReadStream("input.log")
250
+ fs.createReadStream("input.bin")
315
251
  .pipe(createEncodeStream(encoder))
316
- .pipe(fs.createWriteStream("input.log.ddu"));
252
+ .pipe(fs.createWriteStream("output.ddu"));
317
253
 
318
- fs.createReadStream("input.log.ddu")
254
+ fs.createReadStream("output.ddu")
319
255
  .pipe(createDecodeStream(encoder))
320
- .pipe(fs.createWriteStream("input-restored.log"));
321
- ```
322
-
323
- 기본 `createEncodeStream()` 은 작은 스트림 헤더를 함께 기록하고, 기본 `createDecodeStream()` 은 이 헤더를 읽어 압축/암호화 설정을 초기에 auto-detect 합니다. 그래서 기본 경로도 조기 스트리밍 복원이 가능합니다. 암호화된 payload는 동일한 `encryptionKey`가 필요합니다.
324
-
325
- 기존 footer-only 스트림 payload도 계속 디코드됩니다. 다만 과거 포맷은 디코드 쪽에서 전체 payload를 버퍼링할 수 있습니다.
326
-
327
- 헤더 없이 명시적 설정만으로 encode/decode 하려면 양쪽 모두에서 `streamAutoDetect: false` 와 함께 동일한 `compress`, `compressionAlgorithm`, `encryptionKey` 설정을 맞춰 주세요.
328
-
329
- ---
330
-
331
- ## Benchmark
332
-
333
- 대표 시나리오 기준으로 인코딩/디코딩 시간과 샘플링 기반 peak heap 변화를 확인할 수 있습니다.
334
-
335
- ```bash
336
- pnpm bench
256
+ .pipe(fs.createWriteStream("restored.bin"));
337
257
  ```
338
258
 
339
- 벤치마크는 `--expose-gc`로 실행되며, 일반 인코딩, 청크 인코딩, 압축, 암호화 비동기 경로, 공개 스트림 API 조합을 함께 측정합니다.
340
-
341
- 샘플링 기반 측정이므로 profiler 수준의 정확한 peak memory는 아니며, 긴 동기 CPU 구간에서는 실제 피크보다 낮게 보일 수 있습니다.
342
-
343
259
  ---
344
260
 
345
261
  ## API Reference
346
262
 
347
263
  ### `new Ddu64(dduChar?, paddingChar?, options?)`
348
264
 
349
- 인코더 인스턴스를 생성합니다.
350
-
351
- **Parameters:**
352
-
353
265
  | Parameter | Type | Description |
354
266
  | ------------- | ----------------------- | ------------------------ |
355
267
  | `dduChar` | `string \| string[]` | charset 문자열 또는 배열 |
356
268
  | `paddingChar` | `string` | 패딩 문자 |
357
269
  | `options` | `DduConstructorOptions` | 옵션 객체 |
358
270
 
359
- **DduConstructorOptions:**
360
-
361
- | Option | Type | Default | Description |
362
- | ---------------------- | ---------------- | ----------- | --------------------------- |
363
- | `dduSetSymbol` | `DduSetSymbol` | `DDU` | 미리 정의된 charset 심볼 |
364
- | `encoding` | `BufferEncoding` | `'utf-8'` | 문자열 인코딩 |
365
- | `usePowerOfTwo` | `boolean` | `true` | 2의 제곱수 강제 여부 |
366
- | `useBuildErrorReturn` | `boolean` | `false` | 에러 발생 시 throw 여부 |
367
- | `throwOnError` | `boolean` | `false` | 초기화 오류 시 throw 여부 |
368
- | `compress` | `boolean` | `false` | 기본 압축 활성화 |
369
- | `compressionAlgorithm` | `"deflate" \| "brotli"` | `'deflate'` | 기본 압축 알고리즘 |
370
- | `compressionLevel` | `number` | `6` | 압축 레벨 |
371
- | `maxDecodedBytes` | `number` | `67108864` | 최대 디코딩 바이트 (64MB) |
372
- | `maxDecompressedBytes` | `number` | `67108864` | 최대 압축해제 바이트 (64MB) |
373
- | `urlSafe` | `boolean` | `false` | URL-Safe 모드 |
374
- | `encryptionKey` | `string` | `undefined` | AES-256-GCM 암호화 |
375
- | `checksum` | `boolean` | `false` | CRC32 체크섬 활성화 |
376
- | `chunkSize` | `number` | `undefined` | 청크 분할 크기 |
377
- | `chunkSeparator` | `string` | `'\n'` | 청크 구분자 |
378
-
379
- `urlSafe` 는 charset/padding이 `-`, `_`, `.` 를 포함하지 않을 때만 켜집니다. 기본 chunk 정규화와 충돌하므로 custom `charset` 과 `paddingChar` 에는 `\r`, `\n` 을 사용할 수 없습니다.
380
-
381
- ### `encode(data, options?): string`
382
-
383
- 데이터를 인코딩합니다.
384
-
385
- **DduOptions:**
386
-
387
- | Option | Type | Description |
388
- | ------ | ---- | ----------- |
389
- | `compress` | `boolean` | 압축 사용 여부 |
390
- | `streamAutoDetect` | `boolean` | 기본 스트림 헤더 기반 auto-detect 사용 여부 (`false`이면 footer-only 명시 설정 모드) |
391
- | `compressionAlgorithm` | `"deflate" \| "brotli"` | 압축 알고리즘 |
392
- | `compressionLevel` | `number` | 압축 레벨 |
393
- | `checksum` | `boolean` | 체크섬 추가 여부 |
394
- | `maxDecodedBytes` | `number` | 최대 디코딩 바이트 |
395
- | `maxDecompressedBytes` | `number` | 최대 압축해제 바이트 |
396
- | `chunkSize` | `number` | 청크 분할 크기 |
397
- | `chunkSeparator` | `string` | 청크 구분자 |
398
- | `onProgress` | `function` | 진행률 콜백 |
399
-
400
- `encrypt` `omitFooter` 스트림 내부 파이프라인 제어용 옵션이며 일반적인 공개 사용 시에는 직접 지정할 필요가 없습니다.
401
-
402
- ### `decode(encoded, options?): string`
403
-
404
- 인코딩된 문자열을 디코딩합니다.
405
-
406
- ### `decodeToBuffer(encoded, options?): Buffer`
407
-
408
- 인코딩된 문자열을 Buffer로 직접 디코딩합니다.
409
-
410
- ### `encodeAsync(data, options?): Promise<string>`
411
-
412
- 비동기로 데이터를 인코딩합니다.
413
-
414
- ### `decodeAsync(encoded, options?): Promise<string>`
415
-
416
- 비동기로 데이터를 디코딩합니다.
417
-
418
- ### `decodeToBufferAsync(encoded, options?): Promise<Buffer>`
419
-
420
- 비동기로 Buffer로 디코딩합니다.
421
-
422
- ### `getStats(data, options?): DduEncodeStats`
423
-
424
- 인코딩 통계 정보를 반환합니다.
425
-
426
- ```typescript
427
- {
428
- originalSize: number; // 원본 데이터 크기
429
- encodedSize: number; // 인코딩된 문자열 길이
430
- compressedSize?: number; // 압축된 크기
431
- compressionRatio?: number; // 압축률 (0-1)
432
- expansionRatio: number; // 인코딩 확장 비율
433
- charsetSize: number; // charset 크기
434
- bitLength: number; // 비트 길이
435
- }
436
- ```
437
-
438
- ### `getCharSetInfo(): CharSetInfo`
439
-
440
- 현재 인코더의 charset 정보를 반환합니다.
441
-
442
- ---
443
-
444
- ## DduSetSymbol
445
-
446
- | Symbol | 문자 수 | 비트 길이 | 설명 |
447
- | -------------- | ------- | --------- | ------------------------- |
448
- | `DDU` | 8 | 3 | 한글 + 특수문자 기본 세트 |
449
- | `ONECHARSET` | 64 | 6 | 영문 + 숫자 + 특수문자 |
450
- | `TWOCHARSET` | 1024 | 10 | 2글자 조합 세트 |
451
- | `THREECHARSET` | 32768 | 15 | 3글자 조합 세트 |
271
+ **생성자 옵션:**
272
+
273
+ | Option | Type | Default | Description |
274
+ | ---------------------- | ----------------------- | ----------- | ----------------------------- |
275
+ | `dduSetSymbol` | `DduSetSymbol` | `DDU` | 프리셋 심볼 |
276
+ | `codaChar` | `string[]` | | 종성 배열 (동적 charset 생성) |
277
+ | `encoding` | `BufferEncoding` | `'utf-8'` | 문자열 인코딩 |
278
+ | `compress` | `boolean` | `false` | 기본 압축 활성화 |
279
+ | `compressionAlgorithm` | `"deflate" \| "brotli"` | `'deflate'` | 압축 알고리즘 |
280
+ | `compressionLevel` | `number` | `6` | 압축 레벨 |
281
+ | `urlSafe` | `boolean` | `false` | URL-Safe 모드 |
282
+ | `encryptionKey` | `string` | | AES-256-GCM 암호화 키 |
283
+ | `checksum` | `boolean` | `false` | CRC32 체크섬 |
284
+ | `chunkSize` | `number` | | 청크 분할 크기 |
285
+ | `chunkSeparator` | `string` | `'\n'` | 청크 구분자 |
286
+ | `maxDecodedBytes` | `number` | `67108864` | 최대 디코딩 바이트 (64MB) |
287
+ | `maxDecompressedBytes` | `number` | `67108864` | 최대 압축해제 바이트 (64MB) |
288
+ | `throwOnError` | `boolean` | `false` | 초기화 오류 시 throw |
289
+ | `useRepeatPadding` | `boolean` | `false` | 패딩 문자 반복 방식 |
290
+ | `usePowerOfTwo` | `boolean` | `true` | 2의 제곱수 charset 강제 |
291
+
292
+ **메서드:**
293
+
294
+ | Method | Return | Description |
295
+ | ---------------------------------------- | ----------------- | -------------------- |
296
+ | `encode(data, options?)` | `string` | 인코딩 |
297
+ | `decode(encoded, options?)` | `string` | 디코딩 |
298
+ | `decodeToBuffer(encoded, options?)` | `Buffer` | Buffer로 디코딩 |
299
+ | `encodeAsync(data, options?)` | `Promise<string>` | 비동기 인코딩 |
300
+ | `decodeAsync(encoded, options?)` | `Promise<string>` | 비동기 디코딩 |
301
+ | `decodeToBufferAsync(encoded, options?)` | `Promise<Buffer>` | 비동기 Buffer 디코딩 |
302
+ | `getStats(data, options?)` | `DduEncodeStats` | 인코딩 통계 |
303
+ | `getCharSetInfo()` | `CharSetInfo` | charset 정보 |
304
+
305
+ **encode/decode 옵션 (DduOptions):**
306
+
307
+ | Option | Type | Description |
308
+ | ---------------------- | ----------------------- | -------------------- |
309
+ | `compress` | `boolean` | 압축 사용 |
310
+ | `compressionAlgorithm` | `"deflate" \| "brotli"` | 압축 알고리즘 |
311
+ | `compressionLevel` | `number` | 압축 레벨 |
312
+ | `checksum` | `boolean` | 체크섬 추가/검증 |
313
+ | `chunkSize` | `number` | 청크 분할 크기 |
314
+ | `chunkSeparator` | `string` | 청크 구분자 |
315
+ | `maxDecodedBytes` | `number` | 최대 디코딩 바이트 |
316
+ | `maxDecompressedBytes` | `number` | 최대 압축해제 바이트 |
317
+ | `onProgress` | `function` | 진행률 콜백 |
452
318
 
453
319
  ---
454
320
 
455
321
  ## Testing
456
322
 
457
- This project uses [Vitest](https://vitest.dev/) for testing.
458
-
459
323
  ```bash
460
- # Run all tests
461
- pnpm test
462
-
463
- # Run tests in watch mode
464
- pnpm test:watch
324
+ pnpm test # 전체 테스트
325
+ pnpm test:watch # 워치 모드
326
+ pnpm test:coverage # 커버리지
465
327
  ```
466
328
 
467
- ## Verification
329
+ ## Build & Verify
468
330
 
469
331
  ```bash
470
- pnpm lint
471
332
  pnpm build
472
- pnpm test
473
- pnpm pack:check
333
+ pnpm lint
474
334
  pnpm bench
335
+ pnpm pack:check
475
336
  ```
476
337
 
477
338
  ---
478
339
 
340
+ ## Credits
341
+
342
+ - Original: [@i3ls](https://github.com/i3l3), [@gunu3371](https://github.com/gunu3371)
343
+ - Repository: [ddunigma](https://github.com/i3l3/ddunigma)
344
+
479
345
  ## License
480
346
 
481
347
  BSD-2-Clause
@@ -0,0 +1,2 @@
1
+ export{o as DduDecodeStream,n as DduEncodeStream,q as createDecodeStream,p as createEncodeStream}from'./chunk-FVBZKVPE.js';//# sourceMappingURL=DduStream-NP3CMCKK.js.map
2
+ //# sourceMappingURL=DduStream-NP3CMCKK.js.map