@ddunigma/node 1.0.11 → 1.0.13

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,23 +1,326 @@
1
1
  ## ddunigma-node
2
2
 
3
3
  ### Overview
4
+
4
5
  Node.js implementation of [ddunigma](https://github.com/i3l3/ddunigma) (Python original)
5
6
 
6
7
  ### Credits
8
+
7
9
  - Original Python Implementation by:
8
10
  - [@i3ls](https://github.com/i3l3)
9
11
  - [@gunu3371](https://github.com/gunu3371)
10
12
  - Original Repository: [ddunigma](https://github.com/i3l3/ddunigma)
11
13
 
12
14
  ### Usage
15
+
16
+ - Use Basic
17
+
13
18
  ```js
14
- import { Ddu64 } from 'ddunigma-node'
19
+ import { Ddu64 } from "@ddunigma/node";
15
20
 
16
21
  const ddu64 = new Ddu64(); //default encode utf-8
17
22
 
18
- const answer = "뜌땨어 고수가 될거야!"
23
+ const answer = "뜌땨어 고수가 될거야!";
24
+
25
+ const encoded = ddu64.encode(answer);
26
+ console.log(encoded);
27
+ //뜌.뜌이뜌.뜌땨뜌?뜌이뜌땨뜌야뜌.뜌이뜌.뜌땨뜌이뜌?뜌!뜌뜌뜌.뜌우뜌땨뜌땨뜌우뜌이뜌?뜌야뜌땨뜌뜌뜌땨뜌?뜌!뜌이뜌?뜌우뜌!뜌뜌뜌땨뜌?뜌?뜌이뜌땨뜌뜌뜌야뜌?뜌땨뜌?뜌!뜌이뜌?뜌뜌뜌야뜌뜌뜌뜌뜌이뜌뜌뜌우뜌!뜌우뜌야뜌야뜌땨뜌이뜌뜌뜌우뜌!뜌이뜌!뜌야뜌우뜌우뜌뜌뜌우뜌!뜌야뜌야뜌!뜌우뜌우뜌?뜌뜌뜌야뜌땨
28
+ const decoded = ddu64.decode(encoded);
29
+ console.log(decoded);
30
+ //뜌땨어 고수가 될거야!
31
+
32
+ //Encoding Shorter
33
+ const encodedShorter = ddu64.encode(answer, { usePowerOfTwo: true });
34
+ console.log(encodedShorter);
35
+ //.이.땨?이땨야.이.땨이?!뜌.우땨땨우이?야땨뜌땨?!이?우!뜌땨??이땨뜌야?땨?!이?뜌야뜌뜌이뜌우!우야야땨이뜌우!이!야우우뜌우!야야!우우?뜌야땨
36
+ const decodedShorter = ddu64.decode(encodedShorter, { usePowerOfTwo: true });
37
+ console.log(decodedShorter);
38
+ //뜌땨어 고수가 될거야!
39
+ ```
40
+
41
+ - Use Custom Encoding CharSet
42
+
43
+ ```js
44
+ import { Ddu64 } from "@ddunigma/node";
45
+ const koreanChars = [
46
+ // 뜌 계열
47
+ "뜌",
48
+ "뜍",
49
+ "뜎",
50
+ "뜏",
51
+ "뜐",
52
+ "뜑",
53
+ "뜒",
54
+ "뜓",
55
+ "뜔",
56
+ "뜕",
57
+ "뜖",
58
+ "뜗",
59
+ "뜘",
60
+ "뜙",
61
+ "뜚",
62
+ "뜛",
63
+ "뜜",
64
+ "뜝",
65
+ "뜞",
66
+ "뜟",
67
+ "뜠",
68
+ "뜡",
69
+ "뜢",
70
+ "뜣",
71
+ "뜤",
72
+ "뜥",
73
+ "뜦",
74
+ "뜧",
75
+ "뜨",
76
+ "뜩",
77
+ "뜪",
78
+ "뜫",
79
+ "뜬",
80
+ "뜭",
81
+ "뜮",
82
+ "뜯",
83
+ "뜰",
84
+ "뜱",
85
+ "뜲",
86
+ "뜳",
87
+ "뜴",
88
+ "뜵",
89
+ "뜶",
90
+ "뜷",
91
+ "뜸",
92
+ "뜹",
93
+ "뜺",
94
+ "뜻",
95
+ "뜼",
96
+ "뜽",
97
+ "뜾",
98
+ "뜿",
99
+ // 땨 계열
100
+ "땨",
101
+ "땩",
102
+ "땪",
103
+ "땫",
104
+ "땬",
105
+ "땭",
106
+ "땮",
107
+ "땯",
108
+ "땰",
109
+ "땱",
110
+ "땲",
111
+ "땳",
112
+ "땴",
113
+ "땵",
114
+ "땶",
115
+ "땷",
116
+ "땸",
117
+ "땹",
118
+ "땺",
119
+ "땻",
120
+ "땼",
121
+ "땽",
122
+ "땾",
123
+ "땿",
124
+ "떀",
125
+ "떁",
126
+ "떂",
127
+ "떃",
128
+ "떄",
129
+ "떅",
130
+ "떆",
131
+ "떇",
132
+ "떈",
133
+ "떉",
134
+ "떊",
135
+ "떋",
136
+ "떌",
137
+ "떍",
138
+ "떎",
139
+ "떏",
140
+ "떐",
141
+ "떑",
142
+ "떒",
143
+ "떓",
144
+ "떔",
145
+ "떕",
146
+ "떖",
147
+ "떗",
148
+ "떘",
149
+ "떙",
150
+ "떚",
151
+ "떛",
152
+ // 우 계열
153
+ "우",
154
+ "욱",
155
+ "욲",
156
+ "욳",
157
+ "운",
158
+ "울",
159
+ "욶",
160
+ "욷",
161
+ "움",
162
+ "웁",
163
+ "웂",
164
+ "웃",
165
+ "웄",
166
+ "웅",
167
+ "웆",
168
+ "웇",
169
+ "워",
170
+ "웍",
171
+ "웎",
172
+ "웏",
173
+ "원",
174
+ "월",
175
+ "웒",
176
+ "웓",
177
+ "월",
178
+ "웕",
179
+ "웖",
180
+ "웗",
181
+ "웘",
182
+ "웙",
183
+ "웚",
184
+ "웛",
185
+ "위",
186
+ "윅",
187
+ "윆",
188
+ "윇",
189
+ "윈",
190
+ "윉",
191
+ "윊",
192
+ "윋",
193
+ "윌",
194
+ "윍",
195
+ "윎",
196
+ "윏",
197
+ "윐",
198
+ "윑",
199
+ "윒",
200
+ "윓",
201
+ "윔",
202
+ "윕",
203
+ "윖",
204
+ // 따 계열
205
+ "따",
206
+ "딱",
207
+ "딲",
208
+ "딳",
209
+ "딴",
210
+ "딵",
211
+ "딶",
212
+ "딷",
213
+ "딸",
214
+ "딹",
215
+ "딺",
216
+ "딻",
217
+ "딼",
218
+ "딽",
219
+ "딾",
220
+ "딿",
221
+ "땀",
222
+ "땁",
223
+ "땂",
224
+ "땃",
225
+ "땄",
226
+ "땅",
227
+ "땆",
228
+ "땇",
229
+ "땈",
230
+ "땉",
231
+ "땊",
232
+ "땋",
233
+ "때",
234
+ "땍",
235
+ "땎",
236
+ "땏",
237
+ "때",
238
+ "땑",
239
+ "땒",
240
+ "땓",
241
+ "땔",
242
+ "땕",
243
+ "땖",
244
+ "땗",
245
+ "땘",
246
+ "땙",
247
+ "땚",
248
+ "땛",
249
+ "땜",
250
+ "땝",
251
+ "땞",
252
+ "땟",
253
+ "땠",
254
+ "땡",
255
+ "땢",
256
+ // 야 계열
257
+ "야",
258
+ "약",
259
+ "얂",
260
+ "얃",
261
+ "얄",
262
+ "얅",
263
+ "얆",
264
+ "얇",
265
+ "얈",
266
+ "얉",
267
+ "얊",
268
+ "얋",
269
+ "얌",
270
+ "얍",
271
+ "얎",
272
+ "얏",
273
+ "양",
274
+ "양",
275
+ "얒",
276
+ "얓",
277
+ "얔",
278
+ "얕",
279
+ "얖",
280
+ "얗",
281
+ "얘",
282
+ "얙",
283
+ "얚",
284
+ "얛",
285
+ "얜",
286
+ "얝",
287
+ "얞",
288
+ "얟",
289
+ "얠",
290
+ "얡",
291
+ "얢",
292
+ "얣",
293
+ "얤",
294
+ "얥",
295
+ "얦",
296
+ "얧",
297
+ "얨",
298
+ "얩",
299
+ "얪",
300
+ "얫",
301
+ "얬",
302
+ "얭",
303
+ "얮",
304
+ "얯",
305
+ "얰",
306
+ "얱",
307
+ ];
308
+
309
+ const ddu64 = new Ddu64(koreanChars, "뭐");
310
+
311
+ const answer = "안녕하세요";
19
312
  const encoded = ddu64.encode(answer);
20
313
  console.log(encoded);
314
+ //뜌얞뜌윑뜌위뜌얝뜌웙뜌윑뜌얟뜌윑뜌윔뜌얞뜌웘뜌땍뜌얞뜌윖뜌윐
21
315
  const decoded = ddu64.decode(encoded);
22
316
  console.log(decoded);
23
- ```
317
+ //안녕하세요
318
+
319
+ //Encoding Shorter
320
+ const encodedShorter = ddu64.encode(answer, { usePowerOfTwo: true });
321
+ console.log(encodedShorter);
322
+ //얞윑위얝웙윑얟윑윔얞웘땍얞윖윐
323
+ const decodedShorter = ddu64.decode(encodedShorter, { usePowerOfTwo: true });
324
+ console.log(decodedShorter);
325
+ //안녕하세요
326
+ ```
package/dist/cjs/index.js CHANGED
@@ -15,29 +15,18 @@ class Ddu64 {
15
15
  ];
16
16
  this.paddingCharKr = "뭐";
17
17
  this.defaultEncoding = "utf-8";
18
- this.dduChar = dduChar || this.dduCharKr;
19
- this.paddingChar = paddingChar || this.paddingCharKr;
20
18
  this.bitLengthMap = new Map();
21
- this.binaryLookup = new Array(256);
19
+ this.binaryLookup = Array.from({ length: 256 }, (_, i) => i.toString(2).padStart(8, "0"));
22
20
  this.dduBinaryLookup = new Map();
23
21
  this.dduBinaryLookupKr = new Map();
24
22
  this.paddingRegex = new Map();
25
- for (let i = 0; i < 256; i++) {
26
- this.binaryLookup[i] = i.toString(2).padStart(8, "0");
27
- }
28
- this.dduChar.forEach((char, index) => {
29
- this.dduBinaryLookup.set(char, index);
30
- });
31
- this.dduCharKr.forEach((char, index) => {
32
- this.dduBinaryLookupKr.set(char, index);
33
- });
23
+ this.dduChar = dduChar || this.dduCharKr;
24
+ this.paddingChar = paddingChar || this.paddingCharKr;
25
+ this.dduChar.forEach((char, index) => this.dduBinaryLookup.set(char, index));
26
+ this.dduCharKr.forEach((char, index) => this.dduBinaryLookupKr.set(char, index));
34
27
  this.paddingRegex.set("default", new RegExp(this.paddingChar, "g"));
35
28
  this.paddingRegex.set("KR", new RegExp(this.paddingCharKr, "g"));
36
29
  }
37
- getLargestPowerOfTwo(n) {
38
- let power = Math.floor(Math.log2(n));
39
- return Math.pow(2, power);
40
- }
41
30
  getBitLength(setLength) {
42
31
  let cached = this.bitLengthMap.get(setLength);
43
32
  if (cached === undefined) {
@@ -46,43 +35,34 @@ class Ddu64 {
46
35
  }
47
36
  return cached;
48
37
  }
38
+ getLargestPowerOfTwo(n) {
39
+ return Math.pow(2, Math.floor(Math.log2(n)));
40
+ }
49
41
  *splitString(s, length) {
50
- const len = s.length;
51
- for (let i = 0; i < len; i += length) {
52
- yield s.slice(i, Math.min(i + length, len));
42
+ for (let i = 0; i < s.length; i += length) {
43
+ yield s.slice(i, Math.min(i + length, s.length));
53
44
  }
54
45
  }
55
- getSelectedSets(dduSetSymbol) {
56
- if (dduSetSymbol === "KR") {
57
- return {
58
- dduSet: this.dduCharKr,
59
- padChar: this.paddingCharKr,
60
- dduLength: this.dduCharKr.length,
61
- bitLength: this.getBitLength(this.dduCharKr.length),
62
- lookupTable: this.dduBinaryLookupKr,
63
- paddingRegExp: this.paddingRegex.get("KR"),
64
- };
46
+ getSelectedSets(dduSetSymbol, usePowerOfTwo) {
47
+ const isKR = dduSetSymbol === "KR";
48
+ const dduSet = isKR ? this.dduCharKr : this.dduChar;
49
+ const padChar = isKR ? this.paddingCharKr : this.paddingChar;
50
+ let dduLength = dduSet.length;
51
+ if (usePowerOfTwo) {
52
+ const powerOfTwoLength = this.getLargestPowerOfTwo(dduLength);
53
+ dduLength = powerOfTwoLength;
65
54
  }
66
55
  return {
67
- dduSet: this.dduChar,
68
- padChar: this.paddingChar,
69
- dduLength: this.dduChar.length,
70
- bitLength: this.getBitLength(this.dduChar.length),
71
- lookupTable: this.dduBinaryLookup,
72
- paddingRegExp: this.paddingRegex.get("default"),
56
+ dduSet: usePowerOfTwo ? dduSet.slice(0, dduLength) : dduSet,
57
+ padChar,
58
+ dduLength,
59
+ bitLength: this.getBitLength(dduLength),
60
+ lookupTable: isKR ? this.dduBinaryLookupKr : this.dduBinaryLookup,
61
+ paddingRegExp: this.paddingRegex.get(isKR ? "KR" : "default"),
73
62
  };
74
63
  }
75
- getSelectedSets64(option) {
76
- const baseSet = this.getSelectedSets(option);
77
- const powerOfTwoLength = this.getLargestPowerOfTwo(baseSet.dduSet.length);
78
- return Object.assign(Object.assign({}, baseSet), { dduSet: baseSet.dduSet.slice(0, powerOfTwoLength), dduLength: powerOfTwoLength, bitLength: Math.log2(powerOfTwoLength) });
79
- }
80
64
  bufferToDduBinary(input, bitLength) {
81
- const bufferLength = input.length;
82
- let encodedBin = "";
83
- for (let i = 0; i < bufferLength; i++) {
84
- encodedBin += this.binaryLookup[input[i]];
85
- }
65
+ const encodedBin = input.reduce((acc, byte) => acc + this.binaryLookup[byte], "");
86
66
  const dduBinary = Array.from(this.splitString(encodedBin, bitLength));
87
67
  const padding = bitLength - dduBinary[dduBinary.length - 1].length;
88
68
  if (padding > 0) {
@@ -90,86 +70,64 @@ class Ddu64 {
90
70
  }
91
71
  return { dduBinary, padding };
92
72
  }
93
- dduBinaryToBuffer(decodedBin, paddingCount) {
94
- const paddingBits = paddingCount * 2;
73
+ dduBinaryToBuffer(decodedBin, paddingBits) {
95
74
  if (paddingBits > 0) {
96
75
  decodedBin = decodedBin.slice(0, -paddingBits);
97
76
  }
98
- const chunkCount = Math.floor(decodedBin.length / 8);
99
- const buffer = new Array(chunkCount);
100
- for (let i = 0; i < chunkCount; i++) {
101
- const start = i * 8;
102
- buffer[i] = parseInt(decodedBin.slice(start, start + 8), 2);
77
+ const buffer = [];
78
+ for (let i = 0; i < decodedBin.length; i += 8) {
79
+ buffer.push(parseInt(decodedBin.slice(i, i + 8), 2));
103
80
  }
104
- return buffer;
81
+ return Buffer.from(buffer);
105
82
  }
106
83
  encode(input, options = {}) {
107
- options.dduSetSymbol = options.dduSetSymbol || "default";
108
- options.encoding = options.encoding || this.defaultEncoding;
109
- const bufferInput = typeof input === "string" ? Buffer.from(input, options.encoding) : input;
110
- const { dduSet, padChar, dduLength, bitLength } = this.getSelectedSets(options.dduSetSymbol);
111
- const { dduBinary, padding } = this.bufferToDduBinary(bufferInput, bitLength);
112
- let resultString = "";
113
- for (const char of dduBinary) {
114
- const charInt = parseInt(char, 2);
115
- const quotient = Math.floor(charInt / dduLength);
116
- const remainder = charInt % dduLength;
117
- resultString += dduSet[quotient] + dduSet[remainder];
118
- }
119
- if (padding > 0) {
120
- return resultString + padChar.repeat(Math.floor(padding / 2));
121
- }
122
- return resultString;
123
- }
124
- encode64(input, options = {}) {
125
- options.dduSetSymbol = options.dduSetSymbol || "default";
126
- options.encoding = options.encoding || this.defaultEncoding;
127
- const bufferInput = typeof input === "string" ? Buffer.from(input, options.encoding) : input;
128
- const { dduSet, padChar, bitLength } = this.getSelectedSets64(options.dduSetSymbol);
84
+ const { dduSetSymbol = "default", encoding = this.defaultEncoding, usePowerOfTwo = false, } = options;
85
+ const bufferInput = typeof input === "string" ? Buffer.from(input, encoding) : input;
86
+ const { dduSet, padChar, dduLength, bitLength } = this.getSelectedSets(dduSetSymbol, usePowerOfTwo);
129
87
  const { dduBinary, padding } = this.bufferToDduBinary(bufferInput, bitLength);
130
88
  let resultString = "";
131
- for (const char of dduBinary) {
132
- const charInt = parseInt(char, 2);
133
- resultString += dduSet[charInt];
134
- }
135
- if (padding > 0) {
136
- return resultString + padChar.repeat(Math.floor(padding / 2));
89
+ for (const binaryChunk of dduBinary) {
90
+ const charInt = parseInt(binaryChunk, 2);
91
+ if (usePowerOfTwo) {
92
+ resultString += dduSet[charInt];
93
+ }
94
+ else {
95
+ const quotient = Math.floor(charInt / dduLength);
96
+ const remainder = charInt % dduLength;
97
+ resultString += dduSet[quotient] + dduSet[remainder];
98
+ }
137
99
  }
138
- return resultString;
100
+ return padding > 0
101
+ ? resultString + padChar.repeat(Math.floor(padding / 2))
102
+ : resultString;
139
103
  }
140
104
  decode(input, options = {}) {
141
- options.dduSetSymbol = options.dduSetSymbol || "default";
142
- options.encoding = options.encoding || this.defaultEncoding;
143
- const { dduSet, dduLength, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets(options.dduSetSymbol);
144
- const paddingCount = (input.match(paddingRegExp) || []).length;
145
- input = input.replace(paddingRegExp, "");
146
- let dduBinary = "";
147
- for (let i = 0; i < input.length; i += 2) {
148
- const firstIndex = lookupTable.get(input[i]);
149
- const secondIndex = lookupTable.get(input[i + 1]);
150
- if (firstIndex === undefined || secondIndex === undefined)
151
- continue;
152
- const value = firstIndex * dduLength + secondIndex;
153
- dduBinary += value.toString(2).padStart(bitLength, "0");
154
- }
155
- const decoded = this.dduBinaryToBuffer(dduBinary, paddingCount);
156
- return Buffer.from(decoded).toString(options.encoding);
157
- }
158
- decode64(input, options = {}) {
159
- options.dduSetSymbol = options.dduSetSymbol || "default";
160
- options.encoding = options.encoding || this.defaultEncoding;
161
- const { dduSet, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets64(options.dduSetSymbol);
105
+ const { dduSetSymbol = "default", encoding = this.defaultEncoding, usePowerOfTwo = false, } = options;
106
+ const { dduSet, dduLength, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets(dduSetSymbol, usePowerOfTwo);
162
107
  const paddingCount = (input.match(paddingRegExp) || []).length;
108
+ const paddingBits = paddingCount * 2;
163
109
  input = input.replace(paddingRegExp, "");
164
110
  let dduBinary = "";
165
- for (let i = 0; i < input.length; i++) {
166
- const charIndex = lookupTable.get(input[i]);
167
- if (charIndex === undefined)
168
- continue;
169
- dduBinary += charIndex.toString(2).padStart(bitLength, "0");
111
+ for (let i = 0; i < input.length; i += usePowerOfTwo ? 1 : 2) {
112
+ const firstChar = input[i];
113
+ const secondChar = input[i + 1];
114
+ if (usePowerOfTwo) {
115
+ const charIndex = lookupTable.get(firstChar);
116
+ if (charIndex === undefined)
117
+ throw new Error(`Invalid character: ${firstChar}`);
118
+ dduBinary += charIndex.toString(2).padStart(bitLength, "0");
119
+ }
120
+ else {
121
+ const firstIndex = lookupTable.get(firstChar);
122
+ const secondIndex = lookupTable.get(secondChar);
123
+ if (firstIndex === undefined || secondIndex === undefined)
124
+ throw new Error(`Invalid character: ${firstChar} or ${secondChar}`);
125
+ const value = firstIndex * dduLength + secondIndex;
126
+ dduBinary += value.toString(2).padStart(bitLength, "0");
127
+ }
170
128
  }
171
- const decoded = this.dduBinaryToBuffer(dduBinary, paddingCount);
172
- return Buffer.from(decoded).toString(options.encoding);
129
+ const decoded = this.dduBinaryToBuffer(dduBinary, usePowerOfTwo ? paddingBits : paddingCount * bitLength);
130
+ return decoded.toString(encoding);
173
131
  }
174
132
  }
175
133
  exports.Ddu64 = Ddu64;
@@ -26,9 +26,9 @@ const koreanChars = [
26
26
  ]; //129
27
27
  const ddu64 = new __1.Ddu64(["D", "d", "U", "u", "T", "t", "A", "a"], "응");
28
28
  const answer = "안녕 나 안보고싶었어?12";
29
- const encoded = ddu64.encode64(answer);
29
+ const encoded = ddu64.encode(answer, { usePowerOfTwo: true });
30
30
  console.log(encoded);
31
- const decoded = ddu64.decode64(encoded);
31
+ const decoded = ddu64.decode(encoded, { usePowerOfTwo: true });
32
32
  console.log(decoded);
33
33
  console.log("=-==");
34
34
  const encoded_eng = ddu64.encode(answer, { dduSetSymbol: "KR" });
@@ -38,7 +38,7 @@ console.log(decoded_eng);
38
38
  console.log("=-==");
39
39
  const ddu64_other = new __1.Ddu64(koreanChars, "즁");
40
40
  const answer2 = "안녕나안보고싶었어?스스로칭찬하려니까부담되는걸?하지만기록은완성해야하니까어쩔수없지~엘리시아는상냥하고,친근하고,귀엽고,똑똑하고아름다운소녀야.그녀의초대를거절하거나그녀를냉정하게대할수있는사람은없어.전설속의엘프처럼모든이의마음을사로잡고13명의영웅을이곳에모았으면서첫번째자리를양보하는겸손함까지...영웅들에게엘리시아는가장믿음직스럽고사랑받는동료야.너희도그렇게생각하지?1";
41
- const encoded2 = ddu64_other.encode64(answer2);
41
+ const encoded2 = ddu64_other.encode(answer2, { usePowerOfTwo: true });
42
42
  console.log(encoded2);
43
- const decoded2 = ddu64_other.decode64(encoded2);
43
+ const decoded2 = ddu64_other.decode(encoded2, { usePowerOfTwo: true });
44
44
  console.log(decoded2);
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const __1 = require("..");
4
+ function measurePerformance(yaho = -1) {
5
+ const encoderDecoder = new __1.Ddu64();
6
+ const testData = `Hello,${yaho} World! Thi${yaho}s is ${yaho}a per${yaho}formance te${yaho}st for e${yaho}ncod${yaho}ing an${yaho}d decod${yaho}ing.`;
7
+ // 메모리 사용량 측정
8
+ const initialMemoryUsage = process.memoryUsage().heapUsed;
9
+ // CPU 사용량 측정
10
+ const initialCpuUsage = process.cpuUsage();
11
+ // 인코딩 성능 테스트
12
+ const encodeStartTime = performance.now();
13
+ const encodedData = encoderDecoder.encode(testData);
14
+ const encodeEndTime = performance.now();
15
+ const encodeTime = encodeEndTime - encodeStartTime;
16
+ // 디코딩 성능 테스트
17
+ const decodeStartTime = performance.now();
18
+ const decodedData = encoderDecoder.decode(encodedData);
19
+ const decodeEndTime = performance.now();
20
+ const decodeTime = decodeEndTime - decodeStartTime;
21
+ // 메모리 사용량 측정
22
+ const finalMemoryUsage = process.memoryUsage().heapUsed;
23
+ const memoryUsage = finalMemoryUsage - initialMemoryUsage;
24
+ const finalCpuUsage = process.cpuUsage(initialCpuUsage);
25
+ const cpuUsage = finalCpuUsage.user + finalCpuUsage.system;
26
+ return { encodeTime, decodeTime, memoryUsage, cpuUsage };
27
+ }
28
+ const result1 = measurePerformance();
29
+ console.log(`Encode Time: ${result1.encodeTime.toFixed(2)} ms`);
30
+ console.log(`Decode Time: ${result1.decodeTime.toFixed(2)} ms`);
31
+ console.log(`Memory Usage: ${result1.memoryUsage} bytes`);
32
+ console.log(`CPU Usage: ${result1.cpuUsage} microseconds\n`);
33
+ const yaho = 10000;
34
+ let yaho2 = yaho;
35
+ console.log(`loop ${yaho}`);
36
+ while (--yaho2 > 0) {
37
+ const result2 = measurePerformance(yaho);
38
+ result1.encodeTime += result2.encodeTime;
39
+ result1.decodeTime += result2.decodeTime;
40
+ result1.memoryUsage += result2.memoryUsage;
41
+ result1.cpuUsage += result2.cpuUsage;
42
+ }
43
+ console.log(`Encode Time: ${(result1.encodeTime / yaho).toFixed(2)} ms`);
44
+ console.log(`Decode Time: ${(result1.decodeTime / yaho).toFixed(2)} ms`);
45
+ console.log(`Memory Usage: ${result1.memoryUsage / yaho} bytes`);
46
+ console.log(`CPU Usage: ${result1.cpuUsage / yaho} microseconds\n`);
package/dist/index.d.ts CHANGED
@@ -10,27 +10,20 @@ export declare class Ddu64 {
10
10
  private readonly dduBinaryLookupKr;
11
11
  private readonly paddingRegex;
12
12
  constructor(dduChar?: string[], paddingChar?: string);
13
- private getLargestPowerOfTwo;
14
13
  private getBitLength;
14
+ private getLargestPowerOfTwo;
15
15
  private splitString;
16
16
  private getSelectedSets;
17
- private getSelectedSets64;
18
17
  private bufferToDduBinary;
19
18
  private dduBinaryToBuffer;
20
19
  encode(input: Buffer | string, options?: {
21
20
  dduSetSymbol?: string;
22
21
  encoding?: BufferEncoding;
23
- }): string;
24
- encode64(input: Buffer | string, options?: {
25
- dduSetSymbol?: string;
26
- encoding?: BufferEncoding;
22
+ usePowerOfTwo?: boolean;
27
23
  }): string;
28
24
  decode(input: string, options?: {
29
25
  dduSetSymbol?: string;
30
26
  encoding?: BufferEncoding;
31
- }): string;
32
- decode64(input: string, options?: {
33
- dduSetSymbol?: string;
34
- encoding?: BufferEncoding;
27
+ usePowerOfTwo?: boolean;
35
28
  }): string;
36
29
  }
package/dist/mjs/index.js CHANGED
@@ -13,35 +13,19 @@ export class Ddu64 {
13
13
  ];
14
14
  paddingCharKr = "뭐";
15
15
  defaultEncoding = "utf-8";
16
- bitLengthMap;
17
- binaryLookup;
18
- dduBinaryLookup;
19
- dduBinaryLookupKr;
20
- paddingRegex;
16
+ bitLengthMap = new Map();
17
+ binaryLookup = Array.from({ length: 256 }, (_, i) => i.toString(2).padStart(8, "0"));
18
+ dduBinaryLookup = new Map();
19
+ dduBinaryLookupKr = new Map();
20
+ paddingRegex = new Map();
21
21
  constructor(dduChar, paddingChar) {
22
22
  this.dduChar = dduChar || this.dduCharKr;
23
23
  this.paddingChar = paddingChar || this.paddingCharKr;
24
- this.bitLengthMap = new Map();
25
- this.binaryLookup = new Array(256);
26
- this.dduBinaryLookup = new Map();
27
- this.dduBinaryLookupKr = new Map();
28
- this.paddingRegex = new Map();
29
- for (let i = 0; i < 256; i++) {
30
- this.binaryLookup[i] = i.toString(2).padStart(8, "0");
31
- }
32
- this.dduChar.forEach((char, index) => {
33
- this.dduBinaryLookup.set(char, index);
34
- });
35
- this.dduCharKr.forEach((char, index) => {
36
- this.dduBinaryLookupKr.set(char, index);
37
- });
24
+ this.dduChar.forEach((char, index) => this.dduBinaryLookup.set(char, index));
25
+ this.dduCharKr.forEach((char, index) => this.dduBinaryLookupKr.set(char, index));
38
26
  this.paddingRegex.set("default", new RegExp(this.paddingChar, "g"));
39
27
  this.paddingRegex.set("KR", new RegExp(this.paddingCharKr, "g"));
40
28
  }
41
- getLargestPowerOfTwo(n) {
42
- let power = Math.floor(Math.log2(n));
43
- return 2 ** power;
44
- }
45
29
  getBitLength(setLength) {
46
30
  let cached = this.bitLengthMap.get(setLength);
47
31
  if (cached === undefined) {
@@ -50,48 +34,34 @@ export class Ddu64 {
50
34
  }
51
35
  return cached;
52
36
  }
37
+ getLargestPowerOfTwo(n) {
38
+ return 2 ** Math.floor(Math.log2(n));
39
+ }
53
40
  *splitString(s, length) {
54
- const len = s.length;
55
- for (let i = 0; i < len; i += length) {
56
- yield s.slice(i, Math.min(i + length, len));
41
+ for (let i = 0; i < s.length; i += length) {
42
+ yield s.slice(i, Math.min(i + length, s.length));
57
43
  }
58
44
  }
59
- getSelectedSets(dduSetSymbol) {
60
- if (dduSetSymbol === "KR") {
61
- return {
62
- dduSet: this.dduCharKr,
63
- padChar: this.paddingCharKr,
64
- dduLength: this.dduCharKr.length,
65
- bitLength: this.getBitLength(this.dduCharKr.length),
66
- lookupTable: this.dduBinaryLookupKr,
67
- paddingRegExp: this.paddingRegex.get("KR"),
68
- };
45
+ getSelectedSets(dduSetSymbol, usePowerOfTwo) {
46
+ const isKR = dduSetSymbol === "KR";
47
+ const dduSet = isKR ? this.dduCharKr : this.dduChar;
48
+ const padChar = isKR ? this.paddingCharKr : this.paddingChar;
49
+ let dduLength = dduSet.length;
50
+ if (usePowerOfTwo) {
51
+ const powerOfTwoLength = this.getLargestPowerOfTwo(dduLength);
52
+ dduLength = powerOfTwoLength;
69
53
  }
70
54
  return {
71
- dduSet: this.dduChar,
72
- padChar: this.paddingChar,
73
- dduLength: this.dduChar.length,
74
- bitLength: this.getBitLength(this.dduChar.length),
75
- lookupTable: this.dduBinaryLookup,
76
- paddingRegExp: this.paddingRegex.get("default"),
77
- };
78
- }
79
- getSelectedSets64(option) {
80
- const baseSet = this.getSelectedSets(option);
81
- const powerOfTwoLength = this.getLargestPowerOfTwo(baseSet.dduSet.length);
82
- return {
83
- ...baseSet,
84
- dduSet: baseSet.dduSet.slice(0, powerOfTwoLength),
85
- dduLength: powerOfTwoLength,
86
- bitLength: Math.log2(powerOfTwoLength),
55
+ dduSet: usePowerOfTwo ? dduSet.slice(0, dduLength) : dduSet,
56
+ padChar,
57
+ dduLength,
58
+ bitLength: this.getBitLength(dduLength),
59
+ lookupTable: isKR ? this.dduBinaryLookupKr : this.dduBinaryLookup,
60
+ paddingRegExp: this.paddingRegex.get(isKR ? "KR" : "default"),
87
61
  };
88
62
  }
89
63
  bufferToDduBinary(input, bitLength) {
90
- const bufferLength = input.length;
91
- let encodedBin = "";
92
- for (let i = 0; i < bufferLength; i++) {
93
- encodedBin += this.binaryLookup[input[i]];
94
- }
64
+ const encodedBin = input.reduce((acc, byte) => acc + this.binaryLookup[byte], "");
95
65
  const dduBinary = Array.from(this.splitString(encodedBin, bitLength));
96
66
  const padding = bitLength - dduBinary[dduBinary.length - 1].length;
97
67
  if (padding > 0) {
@@ -99,85 +69,63 @@ export class Ddu64 {
99
69
  }
100
70
  return { dduBinary, padding };
101
71
  }
102
- dduBinaryToBuffer(decodedBin, paddingCount) {
103
- const paddingBits = paddingCount * 2;
72
+ dduBinaryToBuffer(decodedBin, paddingBits) {
104
73
  if (paddingBits > 0) {
105
74
  decodedBin = decodedBin.slice(0, -paddingBits);
106
75
  }
107
- const chunkCount = Math.floor(decodedBin.length / 8);
108
- const buffer = new Array(chunkCount);
109
- for (let i = 0; i < chunkCount; i++) {
110
- const start = i * 8;
111
- buffer[i] = parseInt(decodedBin.slice(start, start + 8), 2);
76
+ const buffer = [];
77
+ for (let i = 0; i < decodedBin.length; i += 8) {
78
+ buffer.push(parseInt(decodedBin.slice(i, i + 8), 2));
112
79
  }
113
- return buffer;
80
+ return Buffer.from(buffer);
114
81
  }
115
82
  encode(input, options = {}) {
116
- options.dduSetSymbol = options.dduSetSymbol || "default";
117
- options.encoding = options.encoding || this.defaultEncoding;
118
- const bufferInput = typeof input === "string" ? Buffer.from(input, options.encoding) : input;
119
- const { dduSet, padChar, dduLength, bitLength } = this.getSelectedSets(options.dduSetSymbol);
120
- const { dduBinary, padding } = this.bufferToDduBinary(bufferInput, bitLength);
121
- let resultString = "";
122
- for (const char of dduBinary) {
123
- const charInt = parseInt(char, 2);
124
- const quotient = Math.floor(charInt / dduLength);
125
- const remainder = charInt % dduLength;
126
- resultString += dduSet[quotient] + dduSet[remainder];
127
- }
128
- if (padding > 0) {
129
- return resultString + padChar.repeat(Math.floor(padding / 2));
130
- }
131
- return resultString;
132
- }
133
- encode64(input, options = {}) {
134
- options.dduSetSymbol = options.dduSetSymbol || "default";
135
- options.encoding = options.encoding || this.defaultEncoding;
136
- const bufferInput = typeof input === "string" ? Buffer.from(input, options.encoding) : input;
137
- const { dduSet, padChar, bitLength } = this.getSelectedSets64(options.dduSetSymbol);
83
+ const { dduSetSymbol = "default", encoding = this.defaultEncoding, usePowerOfTwo = false, } = options;
84
+ const bufferInput = typeof input === "string" ? Buffer.from(input, encoding) : input;
85
+ const { dduSet, padChar, dduLength, bitLength } = this.getSelectedSets(dduSetSymbol, usePowerOfTwo);
138
86
  const { dduBinary, padding } = this.bufferToDduBinary(bufferInput, bitLength);
139
87
  let resultString = "";
140
- for (const char of dduBinary) {
141
- const charInt = parseInt(char, 2);
142
- resultString += dduSet[charInt];
143
- }
144
- if (padding > 0) {
145
- return resultString + padChar.repeat(Math.floor(padding / 2));
88
+ for (const binaryChunk of dduBinary) {
89
+ const charInt = parseInt(binaryChunk, 2);
90
+ if (usePowerOfTwo) {
91
+ resultString += dduSet[charInt];
92
+ }
93
+ else {
94
+ const quotient = Math.floor(charInt / dduLength);
95
+ const remainder = charInt % dduLength;
96
+ resultString += dduSet[quotient] + dduSet[remainder];
97
+ }
146
98
  }
147
- return resultString;
99
+ return padding > 0
100
+ ? resultString + padChar.repeat(Math.floor(padding / 2))
101
+ : resultString;
148
102
  }
149
103
  decode(input, options = {}) {
150
- options.dduSetSymbol = options.dduSetSymbol || "default";
151
- options.encoding = options.encoding || this.defaultEncoding;
152
- const { dduSet, dduLength, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets(options.dduSetSymbol);
153
- const paddingCount = (input.match(paddingRegExp) || []).length;
154
- input = input.replace(paddingRegExp, "");
155
- let dduBinary = "";
156
- for (let i = 0; i < input.length; i += 2) {
157
- const firstIndex = lookupTable.get(input[i]);
158
- const secondIndex = lookupTable.get(input[i + 1]);
159
- if (firstIndex === undefined || secondIndex === undefined)
160
- continue;
161
- const value = firstIndex * dduLength + secondIndex;
162
- dduBinary += value.toString(2).padStart(bitLength, "0");
163
- }
164
- const decoded = this.dduBinaryToBuffer(dduBinary, paddingCount);
165
- return Buffer.from(decoded).toString(options.encoding);
166
- }
167
- decode64(input, options = {}) {
168
- options.dduSetSymbol = options.dduSetSymbol || "default";
169
- options.encoding = options.encoding || this.defaultEncoding;
170
- const { dduSet, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets64(options.dduSetSymbol);
104
+ const { dduSetSymbol = "default", encoding = this.defaultEncoding, usePowerOfTwo = false, } = options;
105
+ const { dduSet, dduLength, bitLength, lookupTable, paddingRegExp } = this.getSelectedSets(dduSetSymbol, usePowerOfTwo);
171
106
  const paddingCount = (input.match(paddingRegExp) || []).length;
107
+ const paddingBits = paddingCount * 2;
172
108
  input = input.replace(paddingRegExp, "");
173
109
  let dduBinary = "";
174
- for (let i = 0; i < input.length; i++) {
175
- const charIndex = lookupTable.get(input[i]);
176
- if (charIndex === undefined)
177
- continue;
178
- dduBinary += charIndex.toString(2).padStart(bitLength, "0");
110
+ for (let i = 0; i < input.length; i += usePowerOfTwo ? 1 : 2) {
111
+ const firstChar = input[i];
112
+ const secondChar = input[i + 1];
113
+ if (usePowerOfTwo) {
114
+ const charIndex = lookupTable.get(firstChar);
115
+ if (charIndex === undefined)
116
+ throw new Error(`Invalid character: ${firstChar}`);
117
+ dduBinary += charIndex.toString(2).padStart(bitLength, "0");
118
+ }
119
+ else {
120
+ const firstIndex = lookupTable.get(firstChar);
121
+ const secondIndex = lookupTable.get(secondChar);
122
+ if (firstIndex === undefined || secondIndex === undefined)
123
+ throw new Error(`Invalid character: ${firstChar} or ${secondChar}`);
124
+ const value = firstIndex * dduLength + secondIndex;
125
+ dduBinary += value.toString(2).padStart(bitLength, "0");
126
+ }
179
127
  }
180
- const decoded = this.dduBinaryToBuffer(dduBinary, paddingCount);
181
- return Buffer.from(decoded).toString(options.encoding);
128
+ const decoded = this.dduBinaryToBuffer(dduBinary, usePowerOfTwo ? paddingBits : paddingCount * bitLength);
129
+ return decoded.toString(encoding);
182
130
  }
183
131
  }
@@ -0,0 +1 @@
1
+ export {};
@@ -24,9 +24,9 @@ const koreanChars = [
24
24
  ]; //129
25
25
  const ddu64 = new Ddu64(["D", "d", "U", "u", "T", "t", "A", "a"], "응");
26
26
  const answer = "안녕 나 안보고싶었어?12";
27
- const encoded = ddu64.encode64(answer);
27
+ const encoded = ddu64.encode(answer, { usePowerOfTwo: true });
28
28
  console.log(encoded);
29
- const decoded = ddu64.decode64(encoded);
29
+ const decoded = ddu64.decode(encoded, { usePowerOfTwo: true });
30
30
  console.log(decoded);
31
31
  console.log("=-==");
32
32
  const encoded_eng = ddu64.encode(answer, { dduSetSymbol: "KR" });
@@ -36,7 +36,7 @@ console.log(decoded_eng);
36
36
  console.log("=-==");
37
37
  const ddu64_other = new Ddu64(koreanChars, "즁");
38
38
  const answer2 = "안녕나안보고싶었어?스스로칭찬하려니까부담되는걸?하지만기록은완성해야하니까어쩔수없지~엘리시아는상냥하고,친근하고,귀엽고,똑똑하고아름다운소녀야.그녀의초대를거절하거나그녀를냉정하게대할수있는사람은없어.전설속의엘프처럼모든이의마음을사로잡고13명의영웅을이곳에모았으면서첫번째자리를양보하는겸손함까지...영웅들에게엘리시아는가장믿음직스럽고사랑받는동료야.너희도그렇게생각하지?1";
39
- const encoded2 = ddu64_other.encode64(answer2);
39
+ const encoded2 = ddu64_other.encode(answer2, { usePowerOfTwo: true });
40
40
  console.log(encoded2);
41
- const decoded2 = ddu64_other.decode64(encoded2);
41
+ const decoded2 = ddu64_other.decode(encoded2, { usePowerOfTwo: true });
42
42
  console.log(decoded2);
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import { Ddu64 } from "..";
2
+ function measurePerformance(yaho = -1) {
3
+ const encoderDecoder = new Ddu64();
4
+ const testData = `Hello,${yaho} World! Thi${yaho}s is ${yaho}a per${yaho}formance te${yaho}st for e${yaho}ncod${yaho}ing an${yaho}d decod${yaho}ing.`;
5
+ // 메모리 사용량 측정
6
+ const initialMemoryUsage = process.memoryUsage().heapUsed;
7
+ // CPU 사용량 측정
8
+ const initialCpuUsage = process.cpuUsage();
9
+ // 인코딩 성능 테스트
10
+ const encodeStartTime = performance.now();
11
+ const encodedData = encoderDecoder.encode(testData);
12
+ const encodeEndTime = performance.now();
13
+ const encodeTime = encodeEndTime - encodeStartTime;
14
+ // 디코딩 성능 테스트
15
+ const decodeStartTime = performance.now();
16
+ const decodedData = encoderDecoder.decode(encodedData);
17
+ const decodeEndTime = performance.now();
18
+ const decodeTime = decodeEndTime - decodeStartTime;
19
+ // 메모리 사용량 측정
20
+ const finalMemoryUsage = process.memoryUsage().heapUsed;
21
+ const memoryUsage = finalMemoryUsage - initialMemoryUsage;
22
+ const finalCpuUsage = process.cpuUsage(initialCpuUsage);
23
+ const cpuUsage = finalCpuUsage.user + finalCpuUsage.system;
24
+ return { encodeTime, decodeTime, memoryUsage, cpuUsage };
25
+ }
26
+ const result1 = measurePerformance();
27
+ console.log(`Encode Time: ${result1.encodeTime.toFixed(2)} ms`);
28
+ console.log(`Decode Time: ${result1.decodeTime.toFixed(2)} ms`);
29
+ console.log(`Memory Usage: ${result1.memoryUsage} bytes`);
30
+ console.log(`CPU Usage: ${result1.cpuUsage} microseconds\n`);
31
+ const yaho = 10000;
32
+ let yaho2 = yaho;
33
+ console.log(`loop ${yaho}`);
34
+ while (--yaho2 > 0) {
35
+ const result2 = measurePerformance(yaho);
36
+ result1.encodeTime += result2.encodeTime;
37
+ result1.decodeTime += result2.decodeTime;
38
+ result1.memoryUsage += result2.memoryUsage;
39
+ result1.cpuUsage += result2.cpuUsage;
40
+ }
41
+ console.log(`Encode Time: ${(result1.encodeTime / yaho).toFixed(2)} ms`);
42
+ console.log(`Decode Time: ${(result1.decodeTime / yaho).toFixed(2)} ms`);
43
+ console.log(`Memory Usage: ${result1.memoryUsage / yaho} bytes`);
44
+ console.log(`CPU Usage: ${result1.cpuUsage / yaho} microseconds\n`);
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@ddunigma/node",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/mjs/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "type": "module",
8
8
  "scripts": {
9
- "test": "tsx ./src/test/test.ts",
10
9
  "build": "rm -rf dist/* && tsc -p tsconfig.json && tsc -p tsconfig-cjs.json && sh postProcess.sh",
11
- "test1": "tsx ./src/test/test1.ts"
10
+ "test": "tsx ./src/test/test2.ts",
11
+ "tester": "echo tester2 && tsx ./src/test/tester2.ts && echo tester && tsx ./src/test/tester.ts"
12
12
  },
13
13
  "exports": {
14
14
  ".": {
@@ -23,5 +23,19 @@
23
23
  "@types/node": "^22.13.0",
24
24
  "tsx": "^4.19.2",
25
25
  "typescript": "^5.7.3"
26
- }
26
+ },
27
+ "keywords": [
28
+ "ddu",
29
+ "enigma",
30
+ "Decrypt",
31
+ "Encrypt",
32
+ "Base64",
33
+ "base conversion",
34
+ "base64 encord",
35
+ "base64 decode",
36
+ "base64_encode",
37
+ "base64_decode",
38
+ "encode",
39
+ "decode"
40
+ ]
27
41
  }
File without changes