kidscipher 0.1.0
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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/font.cjs.js +45 -0
- package/dist/font.esm.js +44 -0
- package/dist/index.cjs.js +444 -0
- package/dist/index.esm.js +439 -0
- package/dist/types/cipher/Cipher.d.ts +9 -0
- package/dist/types/cipher/cross/different/DifferentCrossConfig.d.ts +8 -0
- package/dist/types/cipher/cross/hebrew/HebrewCrossConfig.d.ts +7 -0
- package/dist/types/cipher/cross/poland/PolandCrossCipher.d.ts +6 -0
- package/dist/types/cipher/cross/small/SmallCrossConfig.d.ts +8 -0
- package/dist/types/cipher/morsecode/MorseCodeCipher.d.ts +16 -0
- package/dist/types/cipher/shift/ShiftAlphabetCipher.d.ts +13 -0
- package/dist/types/cipher/shift/ShiftCipher.d.ts +15 -0
- package/dist/types/cipher/substitution/SubstitutionCipher.d.ts +9 -0
- package/dist/types/core/cipher-options/CipherOptionsDefault.d.ts +5 -0
- package/dist/types/core/cipher-options/Processor.d.ts +7 -0
- package/dist/types/core/cipher-options/ProcessorPipeline.d.ts +3 -0
- package/dist/types/font.d.ts +1 -0
- package/dist/types/index.d.ts +5 -0
- package/package.json +51 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 fandau1
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# kidscipher
|
|
2
|
+
|
|
3
|
+
Kidscipher is an npm library for encoding and decoding educational and fun ciphers. It mainly provides ciphers that can be solved as a game and also includes a custom font `Kidscipher`, which makes it possible to work with graphical ciphers and symbols.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { PolandCrossCipher } from 'kidscipher';
|
|
9
|
+
|
|
10
|
+
const cipher = new PolandCrossCipher();
|
|
11
|
+
|
|
12
|
+
const encoded = cipher.encode('HELLO');
|
|
13
|
+
console.log(encoded);
|
|
14
|
+
|
|
15
|
+
const decoded = cipher.decode(encoded);
|
|
16
|
+
console.log(decoded); // HELLO
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Custom font
|
|
20
|
+
|
|
21
|
+
The font allows you to render encoded text as graphical symbols (necesary only for graphical outputs). The font is automatically included in the package, so you don’t need to import it separately.
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<p style="font-family: Kidscipher;">{encoded}</p>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Supported Ciphers
|
|
28
|
+
|
|
29
|
+
- ✅ Shift Cipher
|
|
30
|
+
- ✅ Shift Alphabet
|
|
31
|
+
- ❌ ABCD Shift 3-rotor
|
|
32
|
+
- ✅ Substitution Cipher
|
|
33
|
+
- ✅ MorseCode
|
|
34
|
+
- ✅ Poland Cross (need font)
|
|
35
|
+
- ❌ Hebrew Cross (need font)
|
|
36
|
+
- ❌ Small Cross (need font)
|
|
37
|
+
- ❌ Different Cross (need font)
|
|
38
|
+
- ❌ Phone
|
|
39
|
+
- ❌ Chess
|
|
40
|
+
- ❌ Cipher table
|
|
41
|
+
- ❌ Fractions (need font)
|
|
42
|
+
- ❌ Spider-Net Cipher
|
|
43
|
+
- ❌ Chinese Cipher (need font)
|
|
44
|
+
|
|
45
|
+
## Development
|
|
46
|
+
|
|
47
|
+
The main focus of the project is to provide a lightweight, dependency-minimal library with high customization for ciphers.
|
|
48
|
+
|
|
49
|
+
All ciphers are text-based (even the graphical ones).
|
|
50
|
+
The graphical part is powered by the Kidscipher font, which is automatically generated by the script `scripts/generate-font`.
|
|
51
|
+
|
|
52
|
+
This generator maps symbols to Unicode, so every graphical cipher is just normal text rendered with the custom font.
|
|
53
|
+
|
|
54
|
+
### Setup
|
|
55
|
+
|
|
56
|
+
1. Install dependencies:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
npm install
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
2. Prebuild fonts:
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
npm run prebuild-fonts
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
3. Build the package:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm run build
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Local testing in another project
|
|
75
|
+
|
|
76
|
+
To try the package in a different project without publishing to npm, you can link the built `dist` folder directly:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"kidscipher": "file:../dist"
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
> **Note:** After adding the dependency, you **must run `npm install`** in the new project.
|
|
87
|
+
> This will create a symlink to the `../dist` folder, so any updates you rebuild in `kidscipher` will be immediately available in the new project without reinstalling, as long as the folder structure remains the same.
|
|
88
|
+
|
|
89
|
+
## Contributing
|
|
90
|
+
|
|
91
|
+
Contributions are welcome!
|
package/dist/font.cjs.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var KidscipherGlyphs_1;
|
|
4
|
+
var hasRequiredKidscipherGlyphs;
|
|
5
|
+
|
|
6
|
+
function requireKidscipherGlyphs () {
|
|
7
|
+
if (hasRequiredKidscipherGlyphs) return KidscipherGlyphs_1;
|
|
8
|
+
hasRequiredKidscipherGlyphs = 1;
|
|
9
|
+
// Auto-generated by generate-font
|
|
10
|
+
const KidscipherGlyphs = Object.freeze({
|
|
11
|
+
POLAND_CROSS_A: '\u{64}',
|
|
12
|
+
POLAND_CROSS_B: '\u{65}',
|
|
13
|
+
POLAND_CROSS_C: '\u{66}',
|
|
14
|
+
POLAND_CROSS_CH: '\u{67}',
|
|
15
|
+
POLAND_CROSS_D: '\u{68}',
|
|
16
|
+
POLAND_CROSS_E: '\u{69}',
|
|
17
|
+
POLAND_CROSS_F: '\u{6a}',
|
|
18
|
+
POLAND_CROSS_G: '\u{6b}',
|
|
19
|
+
POLAND_CROSS_H: '\u{6c}',
|
|
20
|
+
POLAND_CROSS_I: '\u{6d}',
|
|
21
|
+
POLAND_CROSS_J: '\u{6e}',
|
|
22
|
+
POLAND_CROSS_K: '\u{6f}',
|
|
23
|
+
POLAND_CROSS_L: '\u{70}',
|
|
24
|
+
POLAND_CROSS_M: '\u{71}',
|
|
25
|
+
POLAND_CROSS_N: '\u{72}',
|
|
26
|
+
POLAND_CROSS_O: '\u{73}',
|
|
27
|
+
POLAND_CROSS_P: '\u{74}',
|
|
28
|
+
POLAND_CROSS_Q: '\u{75}',
|
|
29
|
+
POLAND_CROSS_R: '\u{76}',
|
|
30
|
+
POLAND_CROSS_S: '\u{77}',
|
|
31
|
+
POLAND_CROSS_T: '\u{78}',
|
|
32
|
+
POLAND_CROSS_U: '\u{79}',
|
|
33
|
+
POLAND_CROSS_V: '\u{7a}',
|
|
34
|
+
POLAND_CROSS_W: '\u{7b}',
|
|
35
|
+
POLAND_CROSS_X: '\u{7c}',
|
|
36
|
+
POLAND_CROSS_Y: '\u{7d}',
|
|
37
|
+
POLAND_CROSS_Z: '\u{7e}'
|
|
38
|
+
});
|
|
39
|
+
KidscipherGlyphs_1 = { KidscipherGlyphs };
|
|
40
|
+
return KidscipherGlyphs_1;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
var KidscipherGlyphsExports = requireKidscipherGlyphs();
|
|
44
|
+
|
|
45
|
+
exports.KidscipherGlyphs = KidscipherGlyphsExports.KidscipherGlyphs;
|
package/dist/font.esm.js
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
var KidscipherGlyphs_1;
|
|
2
|
+
var hasRequiredKidscipherGlyphs;
|
|
3
|
+
|
|
4
|
+
function requireKidscipherGlyphs () {
|
|
5
|
+
if (hasRequiredKidscipherGlyphs) return KidscipherGlyphs_1;
|
|
6
|
+
hasRequiredKidscipherGlyphs = 1;
|
|
7
|
+
// Auto-generated by generate-font
|
|
8
|
+
const KidscipherGlyphs = Object.freeze({
|
|
9
|
+
POLAND_CROSS_A: '\u{64}',
|
|
10
|
+
POLAND_CROSS_B: '\u{65}',
|
|
11
|
+
POLAND_CROSS_C: '\u{66}',
|
|
12
|
+
POLAND_CROSS_CH: '\u{67}',
|
|
13
|
+
POLAND_CROSS_D: '\u{68}',
|
|
14
|
+
POLAND_CROSS_E: '\u{69}',
|
|
15
|
+
POLAND_CROSS_F: '\u{6a}',
|
|
16
|
+
POLAND_CROSS_G: '\u{6b}',
|
|
17
|
+
POLAND_CROSS_H: '\u{6c}',
|
|
18
|
+
POLAND_CROSS_I: '\u{6d}',
|
|
19
|
+
POLAND_CROSS_J: '\u{6e}',
|
|
20
|
+
POLAND_CROSS_K: '\u{6f}',
|
|
21
|
+
POLAND_CROSS_L: '\u{70}',
|
|
22
|
+
POLAND_CROSS_M: '\u{71}',
|
|
23
|
+
POLAND_CROSS_N: '\u{72}',
|
|
24
|
+
POLAND_CROSS_O: '\u{73}',
|
|
25
|
+
POLAND_CROSS_P: '\u{74}',
|
|
26
|
+
POLAND_CROSS_Q: '\u{75}',
|
|
27
|
+
POLAND_CROSS_R: '\u{76}',
|
|
28
|
+
POLAND_CROSS_S: '\u{77}',
|
|
29
|
+
POLAND_CROSS_T: '\u{78}',
|
|
30
|
+
POLAND_CROSS_U: '\u{79}',
|
|
31
|
+
POLAND_CROSS_V: '\u{7a}',
|
|
32
|
+
POLAND_CROSS_W: '\u{7b}',
|
|
33
|
+
POLAND_CROSS_X: '\u{7c}',
|
|
34
|
+
POLAND_CROSS_Y: '\u{7d}',
|
|
35
|
+
POLAND_CROSS_Z: '\u{7e}'
|
|
36
|
+
});
|
|
37
|
+
KidscipherGlyphs_1 = { KidscipherGlyphs };
|
|
38
|
+
return KidscipherGlyphs_1;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
var KidscipherGlyphsExports = requireKidscipherGlyphs();
|
|
42
|
+
|
|
43
|
+
var KidscipherGlyphs = KidscipherGlyphsExports.KidscipherGlyphs;
|
|
44
|
+
export { KidscipherGlyphs };
|
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function styleInject(css, ref) {
|
|
4
|
+
if ( ref === void 0 ) ref = {};
|
|
5
|
+
var insertAt = ref.insertAt;
|
|
6
|
+
|
|
7
|
+
if (typeof document === 'undefined') { return; }
|
|
8
|
+
|
|
9
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
10
|
+
var style = document.createElement('style');
|
|
11
|
+
style.type = 'text/css';
|
|
12
|
+
|
|
13
|
+
if (insertAt === 'top') {
|
|
14
|
+
if (head.firstChild) {
|
|
15
|
+
head.insertBefore(style, head.firstChild);
|
|
16
|
+
} else {
|
|
17
|
+
head.appendChild(style);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
head.appendChild(style);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (style.styleSheet) {
|
|
24
|
+
style.styleSheet.cssText = css;
|
|
25
|
+
} else {
|
|
26
|
+
style.appendChild(document.createTextNode(css));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var css_248z = "@import './Kidscipher.css';\r\n";
|
|
31
|
+
styleInject(css_248z);
|
|
32
|
+
|
|
33
|
+
class Cipher {
|
|
34
|
+
encode(input, configuration, opts) {
|
|
35
|
+
const { caseSensitive = false, letterSeparator: inputLetterSeparator = '', wordSeparator: inputWordSeparator = '///', } = opts?.input || {};
|
|
36
|
+
const { casing = 'original', letterSeparator: outputLetterSeparator = '', wordSeparator: outputWordSeparator = ' ', } = opts?.output || {};
|
|
37
|
+
// normalize input into words and letters
|
|
38
|
+
const words = input.split(inputWordSeparator);
|
|
39
|
+
const encodedWords = words.map((word) => {
|
|
40
|
+
const letters = inputLetterSeparator
|
|
41
|
+
? word.split(inputLetterSeparator)
|
|
42
|
+
: word.split('');
|
|
43
|
+
return letters
|
|
44
|
+
.map((symbol) => {
|
|
45
|
+
if (/\s/.test(symbol)) {
|
|
46
|
+
return symbol;
|
|
47
|
+
}
|
|
48
|
+
const c = caseSensitive ? symbol : symbol.toUpperCase();
|
|
49
|
+
let encoded = this.encodeToken(c, configuration);
|
|
50
|
+
if (casing === 'upper')
|
|
51
|
+
encoded = encoded.toUpperCase();
|
|
52
|
+
if (casing === 'lower')
|
|
53
|
+
encoded = encoded.toLowerCase();
|
|
54
|
+
return encoded;
|
|
55
|
+
})
|
|
56
|
+
.join(outputLetterSeparator);
|
|
57
|
+
});
|
|
58
|
+
return encodedWords.join(outputWordSeparator);
|
|
59
|
+
}
|
|
60
|
+
decode(input, configuration, opts) {
|
|
61
|
+
const { caseSensitive = false, letterSeparator: inputLetterSeparator = '', wordSeparator: inputWordSeparator = ' ', } = opts?.input || {};
|
|
62
|
+
const { casing = 'original', letterSeparator: outputLetterSeparator = '', wordSeparator: outputWordSeparator = ' ', } = opts?.output || {};
|
|
63
|
+
// split encoded text into words
|
|
64
|
+
const words = input.split(inputWordSeparator);
|
|
65
|
+
const decodedWords = words.map((word) => {
|
|
66
|
+
const symbols = word.split(inputLetterSeparator);
|
|
67
|
+
return symbols
|
|
68
|
+
.map((symbol) => {
|
|
69
|
+
if (/\s/.test(symbol)) {
|
|
70
|
+
return symbol;
|
|
71
|
+
}
|
|
72
|
+
const c = caseSensitive ? symbol : symbol.toUpperCase();
|
|
73
|
+
let decoded = this.decodeToken(c, configuration);
|
|
74
|
+
if (casing === 'upper')
|
|
75
|
+
decoded = decoded.toUpperCase();
|
|
76
|
+
if (casing === 'lower')
|
|
77
|
+
decoded = decoded.toLowerCase();
|
|
78
|
+
return decoded;
|
|
79
|
+
})
|
|
80
|
+
.join(outputLetterSeparator);
|
|
81
|
+
});
|
|
82
|
+
return decodedWords.join(outputWordSeparator);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
class SubstitutionCipher extends Cipher {
|
|
87
|
+
constructor(encodeMap) {
|
|
88
|
+
super();
|
|
89
|
+
this.encodeMap = encodeMap;
|
|
90
|
+
this.decodeMap = Object.entries(encodeMap).reduce((acc, [key, value]) => ({ ...acc, [value]: key }), {});
|
|
91
|
+
}
|
|
92
|
+
encodeToken(token) {
|
|
93
|
+
return this.encodeMap[token] ?? '';
|
|
94
|
+
}
|
|
95
|
+
decodeToken(token) {
|
|
96
|
+
let decoded = this.decodeMap[token] ?? '';
|
|
97
|
+
return decoded;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function withDefaultCipherOptions(opts, defaults) {
|
|
102
|
+
return {
|
|
103
|
+
input: {
|
|
104
|
+
caseSensitive: false,
|
|
105
|
+
letterSeparator: '',
|
|
106
|
+
wordSeparator: ' ',
|
|
107
|
+
...defaults?.input,
|
|
108
|
+
...opts?.input,
|
|
109
|
+
},
|
|
110
|
+
output: {
|
|
111
|
+
casing: 'original',
|
|
112
|
+
letterSeparator: '',
|
|
113
|
+
wordSeparator: ' ',
|
|
114
|
+
...defaults?.output,
|
|
115
|
+
...opts?.output,
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
class MorseCodeCipher extends SubstitutionCipher {
|
|
121
|
+
constructor() {
|
|
122
|
+
super(MorseCodeCipher.MORSE_CODE_MAP);
|
|
123
|
+
}
|
|
124
|
+
encode(input, configuration, opts) {
|
|
125
|
+
const { dotDashMapping = { dot: '.', dash: '-' } } = configuration || {};
|
|
126
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
127
|
+
input: {
|
|
128
|
+
caseSensitive: true,
|
|
129
|
+
letterSeparator: '',
|
|
130
|
+
wordSeparator: ' ',
|
|
131
|
+
},
|
|
132
|
+
output: {
|
|
133
|
+
casing: 'original',
|
|
134
|
+
letterSeparator: '/',
|
|
135
|
+
wordSeparator: '///',
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
const encoded = super.encode(input, configuration, mergedOpts);
|
|
139
|
+
if (dotDashMapping) {
|
|
140
|
+
return encoded
|
|
141
|
+
.split('')
|
|
142
|
+
.map((char) => {
|
|
143
|
+
if (char === '.')
|
|
144
|
+
return dotDashMapping.dot;
|
|
145
|
+
if (char === '-')
|
|
146
|
+
return dotDashMapping.dash;
|
|
147
|
+
return char;
|
|
148
|
+
})
|
|
149
|
+
.join('');
|
|
150
|
+
}
|
|
151
|
+
return encoded;
|
|
152
|
+
}
|
|
153
|
+
decode(input, configuration, opts) {
|
|
154
|
+
const { dotDashMapping = { dot: '.', dash: '-' } } = configuration || {};
|
|
155
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
156
|
+
input: {
|
|
157
|
+
caseSensitive: true,
|
|
158
|
+
letterSeparator: '/',
|
|
159
|
+
wordSeparator: '///',
|
|
160
|
+
},
|
|
161
|
+
output: { casing: 'lower', letterSeparator: '', wordSeparator: ' ' },
|
|
162
|
+
});
|
|
163
|
+
let normalized = input;
|
|
164
|
+
if (dotDashMapping) {
|
|
165
|
+
// Map custom symbols back to "." and "-"
|
|
166
|
+
normalized = input
|
|
167
|
+
.split('')
|
|
168
|
+
.map((char) => {
|
|
169
|
+
if (char === dotDashMapping.dot)
|
|
170
|
+
return '.';
|
|
171
|
+
if (char === dotDashMapping.dash)
|
|
172
|
+
return '-';
|
|
173
|
+
return char;
|
|
174
|
+
})
|
|
175
|
+
.join('');
|
|
176
|
+
}
|
|
177
|
+
return super.decode(normalized, configuration, mergedOpts);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
MorseCodeCipher.MORSE_CODE_MAP = {
|
|
181
|
+
A: '.-',
|
|
182
|
+
B: '-...',
|
|
183
|
+
C: '-.-.',
|
|
184
|
+
D: '-..',
|
|
185
|
+
E: '.',
|
|
186
|
+
F: '..-.',
|
|
187
|
+
G: '--.',
|
|
188
|
+
H: '....',
|
|
189
|
+
I: '..',
|
|
190
|
+
J: '.---',
|
|
191
|
+
K: '-.-',
|
|
192
|
+
L: '.-..',
|
|
193
|
+
M: '--',
|
|
194
|
+
N: '-.',
|
|
195
|
+
O: '---',
|
|
196
|
+
P: '.--.',
|
|
197
|
+
Q: '--.-',
|
|
198
|
+
R: '.-.',
|
|
199
|
+
S: '...',
|
|
200
|
+
T: '-',
|
|
201
|
+
U: '..-',
|
|
202
|
+
V: '...-',
|
|
203
|
+
W: '.--',
|
|
204
|
+
X: '-..-',
|
|
205
|
+
Y: '-.--',
|
|
206
|
+
Z: '--..',
|
|
207
|
+
'0': '-----',
|
|
208
|
+
'1': '.----',
|
|
209
|
+
'2': '..---',
|
|
210
|
+
'3': '...--',
|
|
211
|
+
'4': '....-',
|
|
212
|
+
'5': '.....',
|
|
213
|
+
'6': '-....',
|
|
214
|
+
'7': '--...',
|
|
215
|
+
'8': '---..',
|
|
216
|
+
'9': '----.',
|
|
217
|
+
};
|
|
218
|
+
|
|
219
|
+
var KidscipherGlyphs_1;
|
|
220
|
+
var hasRequiredKidscipherGlyphs;
|
|
221
|
+
|
|
222
|
+
function requireKidscipherGlyphs () {
|
|
223
|
+
if (hasRequiredKidscipherGlyphs) return KidscipherGlyphs_1;
|
|
224
|
+
hasRequiredKidscipherGlyphs = 1;
|
|
225
|
+
// Auto-generated by generate-font
|
|
226
|
+
const KidscipherGlyphs = Object.freeze({
|
|
227
|
+
POLAND_CROSS_A: '\u{64}',
|
|
228
|
+
POLAND_CROSS_B: '\u{65}',
|
|
229
|
+
POLAND_CROSS_C: '\u{66}',
|
|
230
|
+
POLAND_CROSS_CH: '\u{67}',
|
|
231
|
+
POLAND_CROSS_D: '\u{68}',
|
|
232
|
+
POLAND_CROSS_E: '\u{69}',
|
|
233
|
+
POLAND_CROSS_F: '\u{6a}',
|
|
234
|
+
POLAND_CROSS_G: '\u{6b}',
|
|
235
|
+
POLAND_CROSS_H: '\u{6c}',
|
|
236
|
+
POLAND_CROSS_I: '\u{6d}',
|
|
237
|
+
POLAND_CROSS_J: '\u{6e}',
|
|
238
|
+
POLAND_CROSS_K: '\u{6f}',
|
|
239
|
+
POLAND_CROSS_L: '\u{70}',
|
|
240
|
+
POLAND_CROSS_M: '\u{71}',
|
|
241
|
+
POLAND_CROSS_N: '\u{72}',
|
|
242
|
+
POLAND_CROSS_O: '\u{73}',
|
|
243
|
+
POLAND_CROSS_P: '\u{74}',
|
|
244
|
+
POLAND_CROSS_Q: '\u{75}',
|
|
245
|
+
POLAND_CROSS_R: '\u{76}',
|
|
246
|
+
POLAND_CROSS_S: '\u{77}',
|
|
247
|
+
POLAND_CROSS_T: '\u{78}',
|
|
248
|
+
POLAND_CROSS_U: '\u{79}',
|
|
249
|
+
POLAND_CROSS_V: '\u{7a}',
|
|
250
|
+
POLAND_CROSS_W: '\u{7b}',
|
|
251
|
+
POLAND_CROSS_X: '\u{7c}',
|
|
252
|
+
POLAND_CROSS_Y: '\u{7d}',
|
|
253
|
+
POLAND_CROSS_Z: '\u{7e}'
|
|
254
|
+
});
|
|
255
|
+
KidscipherGlyphs_1 = { KidscipherGlyphs };
|
|
256
|
+
return KidscipherGlyphs_1;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
var KidscipherGlyphsExports = requireKidscipherGlyphs();
|
|
260
|
+
|
|
261
|
+
class PolandCrossCipher extends SubstitutionCipher {
|
|
262
|
+
constructor() {
|
|
263
|
+
super(PolandCrossCipher.POLAND_CROSS_MAP);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
PolandCrossCipher.POLAND_CROSS_MAP = {
|
|
267
|
+
A: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_A,
|
|
268
|
+
B: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_B,
|
|
269
|
+
C: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_C,
|
|
270
|
+
D: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_D,
|
|
271
|
+
E: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_E,
|
|
272
|
+
F: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_F,
|
|
273
|
+
G: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_G,
|
|
274
|
+
H: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_H,
|
|
275
|
+
CH: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_CH,
|
|
276
|
+
I: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_I,
|
|
277
|
+
J: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_J,
|
|
278
|
+
K: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_K,
|
|
279
|
+
L: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_L,
|
|
280
|
+
M: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_M,
|
|
281
|
+
N: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_N,
|
|
282
|
+
O: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_O,
|
|
283
|
+
P: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_P,
|
|
284
|
+
Q: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Q,
|
|
285
|
+
R: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_R,
|
|
286
|
+
S: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_S,
|
|
287
|
+
T: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_T,
|
|
288
|
+
U: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_U,
|
|
289
|
+
V: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_V,
|
|
290
|
+
W: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_W,
|
|
291
|
+
X: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_X,
|
|
292
|
+
Y: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Y,
|
|
293
|
+
Z: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Z,
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
class ShiftCipher extends Cipher {
|
|
297
|
+
constructor(baseAlphabet, rotors) {
|
|
298
|
+
super();
|
|
299
|
+
// Check all alphabets have the same length
|
|
300
|
+
for (const alpha of rotors) {
|
|
301
|
+
if (alpha.length !== baseAlphabet.length) {
|
|
302
|
+
throw new Error('All alphabets must have the same length');
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
this.baseAlphabet = baseAlphabet;
|
|
306
|
+
this.rotors = rotors;
|
|
307
|
+
}
|
|
308
|
+
encodeToken(token, configuration) {
|
|
309
|
+
const { shifts } = configuration;
|
|
310
|
+
let encoded = '';
|
|
311
|
+
if (this.baseAlphabet.includes(token)) {
|
|
312
|
+
const index = this.baseAlphabet.indexOf(token);
|
|
313
|
+
for (let i = 0; i < this.rotors.length; i++) {
|
|
314
|
+
const wheel = this.rotors[i];
|
|
315
|
+
const shiftedIndex = (index + shifts[i]) % wheel.length;
|
|
316
|
+
encoded += wheel[shiftedIndex];
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return encoded;
|
|
320
|
+
}
|
|
321
|
+
encode(input, configuration, opts) {
|
|
322
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
323
|
+
input: {
|
|
324
|
+
caseSensitive: false,
|
|
325
|
+
letterSeparator: '',
|
|
326
|
+
wordSeparator: ' ',
|
|
327
|
+
},
|
|
328
|
+
output: {
|
|
329
|
+
casing: 'original',
|
|
330
|
+
letterSeparator: '',
|
|
331
|
+
wordSeparator: ' ',
|
|
332
|
+
},
|
|
333
|
+
});
|
|
334
|
+
return super.encode(input, configuration, mergedOpts);
|
|
335
|
+
}
|
|
336
|
+
decodeToken(token, configuration) {
|
|
337
|
+
const { shifts } = configuration;
|
|
338
|
+
let encoded = '';
|
|
339
|
+
if (token.length === this.rotors.length) {
|
|
340
|
+
let currentIndex = -1;
|
|
341
|
+
for (let i = this.rotors.length - 1; 0 <= i; i--) {
|
|
342
|
+
if (this.rotors[i].includes(token[i])) {
|
|
343
|
+
currentIndex = this.rotors[i].indexOf(token[i]);
|
|
344
|
+
currentIndex =
|
|
345
|
+
(currentIndex - shifts[i] + this.baseAlphabet.length) %
|
|
346
|
+
this.baseAlphabet.length;
|
|
347
|
+
}
|
|
348
|
+
else {
|
|
349
|
+
// invalid token
|
|
350
|
+
return '';
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
encoded = this.baseAlphabet[currentIndex];
|
|
354
|
+
}
|
|
355
|
+
return encoded;
|
|
356
|
+
}
|
|
357
|
+
decode(input, configuration, opts) {
|
|
358
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
359
|
+
input: {
|
|
360
|
+
caseSensitive: false,
|
|
361
|
+
letterSeparator: '',
|
|
362
|
+
wordSeparator: ' ',
|
|
363
|
+
},
|
|
364
|
+
output: {
|
|
365
|
+
casing: 'original',
|
|
366
|
+
letterSeparator: '',
|
|
367
|
+
wordSeparator: ' ',
|
|
368
|
+
},
|
|
369
|
+
});
|
|
370
|
+
return super.decode(input, configuration, mergedOpts);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
class ShiftAlphabetCipher extends ShiftCipher {
|
|
375
|
+
constructor(alphabet) {
|
|
376
|
+
if (!alphabet) {
|
|
377
|
+
alphabet = ShiftAlphabetCipher.DEFAULT_ALPHABET;
|
|
378
|
+
}
|
|
379
|
+
super(alphabet, [alphabet]);
|
|
380
|
+
}
|
|
381
|
+
encode(input, { shift }, opts) {
|
|
382
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
383
|
+
input: {
|
|
384
|
+
caseSensitive: false,
|
|
385
|
+
letterSeparator: '',
|
|
386
|
+
wordSeparator: ' ',
|
|
387
|
+
},
|
|
388
|
+
output: {
|
|
389
|
+
casing: 'original',
|
|
390
|
+
letterSeparator: '',
|
|
391
|
+
wordSeparator: ' ',
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
return super.encode(input, { shifts: [shift] }, mergedOpts);
|
|
395
|
+
}
|
|
396
|
+
decode(input, { shift }, opts) {
|
|
397
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
398
|
+
input: {
|
|
399
|
+
caseSensitive: false,
|
|
400
|
+
letterSeparator: '',
|
|
401
|
+
wordSeparator: ' ',
|
|
402
|
+
},
|
|
403
|
+
output: {
|
|
404
|
+
casing: 'original',
|
|
405
|
+
letterSeparator: '',
|
|
406
|
+
wordSeparator: ' ',
|
|
407
|
+
},
|
|
408
|
+
});
|
|
409
|
+
return super.decode(input, { shifts: [shift] }, mergedOpts);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
ShiftAlphabetCipher.DEFAULT_ALPHABET = [
|
|
413
|
+
'A',
|
|
414
|
+
'B',
|
|
415
|
+
'C',
|
|
416
|
+
'D',
|
|
417
|
+
'E',
|
|
418
|
+
'F',
|
|
419
|
+
'G',
|
|
420
|
+
'H',
|
|
421
|
+
'I',
|
|
422
|
+
'J',
|
|
423
|
+
'K',
|
|
424
|
+
'L',
|
|
425
|
+
'M',
|
|
426
|
+
'N',
|
|
427
|
+
'O',
|
|
428
|
+
'P',
|
|
429
|
+
'Q',
|
|
430
|
+
'R',
|
|
431
|
+
'S',
|
|
432
|
+
'T',
|
|
433
|
+
'U',
|
|
434
|
+
'V',
|
|
435
|
+
'W',
|
|
436
|
+
'X',
|
|
437
|
+
'Y',
|
|
438
|
+
'Z',
|
|
439
|
+
];
|
|
440
|
+
|
|
441
|
+
exports.MorseCodeCipher = MorseCodeCipher;
|
|
442
|
+
exports.PolandCrossCipher = PolandCrossCipher;
|
|
443
|
+
exports.ShiftAlphabetCipher = ShiftAlphabetCipher;
|
|
444
|
+
exports.SubstitutionCipher = SubstitutionCipher;
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
function styleInject(css, ref) {
|
|
2
|
+
if ( ref === void 0 ) ref = {};
|
|
3
|
+
var insertAt = ref.insertAt;
|
|
4
|
+
|
|
5
|
+
if (typeof document === 'undefined') { return; }
|
|
6
|
+
|
|
7
|
+
var head = document.head || document.getElementsByTagName('head')[0];
|
|
8
|
+
var style = document.createElement('style');
|
|
9
|
+
style.type = 'text/css';
|
|
10
|
+
|
|
11
|
+
if (insertAt === 'top') {
|
|
12
|
+
if (head.firstChild) {
|
|
13
|
+
head.insertBefore(style, head.firstChild);
|
|
14
|
+
} else {
|
|
15
|
+
head.appendChild(style);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
head.appendChild(style);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (style.styleSheet) {
|
|
22
|
+
style.styleSheet.cssText = css;
|
|
23
|
+
} else {
|
|
24
|
+
style.appendChild(document.createTextNode(css));
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var css_248z = "@import './Kidscipher.css';\r\n";
|
|
29
|
+
styleInject(css_248z);
|
|
30
|
+
|
|
31
|
+
class Cipher {
|
|
32
|
+
encode(input, configuration, opts) {
|
|
33
|
+
const { caseSensitive = false, letterSeparator: inputLetterSeparator = '', wordSeparator: inputWordSeparator = '///', } = opts?.input || {};
|
|
34
|
+
const { casing = 'original', letterSeparator: outputLetterSeparator = '', wordSeparator: outputWordSeparator = ' ', } = opts?.output || {};
|
|
35
|
+
// normalize input into words and letters
|
|
36
|
+
const words = input.split(inputWordSeparator);
|
|
37
|
+
const encodedWords = words.map((word) => {
|
|
38
|
+
const letters = inputLetterSeparator
|
|
39
|
+
? word.split(inputLetterSeparator)
|
|
40
|
+
: word.split('');
|
|
41
|
+
return letters
|
|
42
|
+
.map((symbol) => {
|
|
43
|
+
if (/\s/.test(symbol)) {
|
|
44
|
+
return symbol;
|
|
45
|
+
}
|
|
46
|
+
const c = caseSensitive ? symbol : symbol.toUpperCase();
|
|
47
|
+
let encoded = this.encodeToken(c, configuration);
|
|
48
|
+
if (casing === 'upper')
|
|
49
|
+
encoded = encoded.toUpperCase();
|
|
50
|
+
if (casing === 'lower')
|
|
51
|
+
encoded = encoded.toLowerCase();
|
|
52
|
+
return encoded;
|
|
53
|
+
})
|
|
54
|
+
.join(outputLetterSeparator);
|
|
55
|
+
});
|
|
56
|
+
return encodedWords.join(outputWordSeparator);
|
|
57
|
+
}
|
|
58
|
+
decode(input, configuration, opts) {
|
|
59
|
+
const { caseSensitive = false, letterSeparator: inputLetterSeparator = '', wordSeparator: inputWordSeparator = ' ', } = opts?.input || {};
|
|
60
|
+
const { casing = 'original', letterSeparator: outputLetterSeparator = '', wordSeparator: outputWordSeparator = ' ', } = opts?.output || {};
|
|
61
|
+
// split encoded text into words
|
|
62
|
+
const words = input.split(inputWordSeparator);
|
|
63
|
+
const decodedWords = words.map((word) => {
|
|
64
|
+
const symbols = word.split(inputLetterSeparator);
|
|
65
|
+
return symbols
|
|
66
|
+
.map((symbol) => {
|
|
67
|
+
if (/\s/.test(symbol)) {
|
|
68
|
+
return symbol;
|
|
69
|
+
}
|
|
70
|
+
const c = caseSensitive ? symbol : symbol.toUpperCase();
|
|
71
|
+
let decoded = this.decodeToken(c, configuration);
|
|
72
|
+
if (casing === 'upper')
|
|
73
|
+
decoded = decoded.toUpperCase();
|
|
74
|
+
if (casing === 'lower')
|
|
75
|
+
decoded = decoded.toLowerCase();
|
|
76
|
+
return decoded;
|
|
77
|
+
})
|
|
78
|
+
.join(outputLetterSeparator);
|
|
79
|
+
});
|
|
80
|
+
return decodedWords.join(outputWordSeparator);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
class SubstitutionCipher extends Cipher {
|
|
85
|
+
constructor(encodeMap) {
|
|
86
|
+
super();
|
|
87
|
+
this.encodeMap = encodeMap;
|
|
88
|
+
this.decodeMap = Object.entries(encodeMap).reduce((acc, [key, value]) => ({ ...acc, [value]: key }), {});
|
|
89
|
+
}
|
|
90
|
+
encodeToken(token) {
|
|
91
|
+
return this.encodeMap[token] ?? '';
|
|
92
|
+
}
|
|
93
|
+
decodeToken(token) {
|
|
94
|
+
let decoded = this.decodeMap[token] ?? '';
|
|
95
|
+
return decoded;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function withDefaultCipherOptions(opts, defaults) {
|
|
100
|
+
return {
|
|
101
|
+
input: {
|
|
102
|
+
caseSensitive: false,
|
|
103
|
+
letterSeparator: '',
|
|
104
|
+
wordSeparator: ' ',
|
|
105
|
+
...defaults?.input,
|
|
106
|
+
...opts?.input,
|
|
107
|
+
},
|
|
108
|
+
output: {
|
|
109
|
+
casing: 'original',
|
|
110
|
+
letterSeparator: '',
|
|
111
|
+
wordSeparator: ' ',
|
|
112
|
+
...defaults?.output,
|
|
113
|
+
...opts?.output,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
class MorseCodeCipher extends SubstitutionCipher {
|
|
119
|
+
constructor() {
|
|
120
|
+
super(MorseCodeCipher.MORSE_CODE_MAP);
|
|
121
|
+
}
|
|
122
|
+
encode(input, configuration, opts) {
|
|
123
|
+
const { dotDashMapping = { dot: '.', dash: '-' } } = configuration || {};
|
|
124
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
125
|
+
input: {
|
|
126
|
+
caseSensitive: true,
|
|
127
|
+
letterSeparator: '',
|
|
128
|
+
wordSeparator: ' ',
|
|
129
|
+
},
|
|
130
|
+
output: {
|
|
131
|
+
casing: 'original',
|
|
132
|
+
letterSeparator: '/',
|
|
133
|
+
wordSeparator: '///',
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
const encoded = super.encode(input, configuration, mergedOpts);
|
|
137
|
+
if (dotDashMapping) {
|
|
138
|
+
return encoded
|
|
139
|
+
.split('')
|
|
140
|
+
.map((char) => {
|
|
141
|
+
if (char === '.')
|
|
142
|
+
return dotDashMapping.dot;
|
|
143
|
+
if (char === '-')
|
|
144
|
+
return dotDashMapping.dash;
|
|
145
|
+
return char;
|
|
146
|
+
})
|
|
147
|
+
.join('');
|
|
148
|
+
}
|
|
149
|
+
return encoded;
|
|
150
|
+
}
|
|
151
|
+
decode(input, configuration, opts) {
|
|
152
|
+
const { dotDashMapping = { dot: '.', dash: '-' } } = configuration || {};
|
|
153
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
154
|
+
input: {
|
|
155
|
+
caseSensitive: true,
|
|
156
|
+
letterSeparator: '/',
|
|
157
|
+
wordSeparator: '///',
|
|
158
|
+
},
|
|
159
|
+
output: { casing: 'lower', letterSeparator: '', wordSeparator: ' ' },
|
|
160
|
+
});
|
|
161
|
+
let normalized = input;
|
|
162
|
+
if (dotDashMapping) {
|
|
163
|
+
// Map custom symbols back to "." and "-"
|
|
164
|
+
normalized = input
|
|
165
|
+
.split('')
|
|
166
|
+
.map((char) => {
|
|
167
|
+
if (char === dotDashMapping.dot)
|
|
168
|
+
return '.';
|
|
169
|
+
if (char === dotDashMapping.dash)
|
|
170
|
+
return '-';
|
|
171
|
+
return char;
|
|
172
|
+
})
|
|
173
|
+
.join('');
|
|
174
|
+
}
|
|
175
|
+
return super.decode(normalized, configuration, mergedOpts);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
MorseCodeCipher.MORSE_CODE_MAP = {
|
|
179
|
+
A: '.-',
|
|
180
|
+
B: '-...',
|
|
181
|
+
C: '-.-.',
|
|
182
|
+
D: '-..',
|
|
183
|
+
E: '.',
|
|
184
|
+
F: '..-.',
|
|
185
|
+
G: '--.',
|
|
186
|
+
H: '....',
|
|
187
|
+
I: '..',
|
|
188
|
+
J: '.---',
|
|
189
|
+
K: '-.-',
|
|
190
|
+
L: '.-..',
|
|
191
|
+
M: '--',
|
|
192
|
+
N: '-.',
|
|
193
|
+
O: '---',
|
|
194
|
+
P: '.--.',
|
|
195
|
+
Q: '--.-',
|
|
196
|
+
R: '.-.',
|
|
197
|
+
S: '...',
|
|
198
|
+
T: '-',
|
|
199
|
+
U: '..-',
|
|
200
|
+
V: '...-',
|
|
201
|
+
W: '.--',
|
|
202
|
+
X: '-..-',
|
|
203
|
+
Y: '-.--',
|
|
204
|
+
Z: '--..',
|
|
205
|
+
'0': '-----',
|
|
206
|
+
'1': '.----',
|
|
207
|
+
'2': '..---',
|
|
208
|
+
'3': '...--',
|
|
209
|
+
'4': '....-',
|
|
210
|
+
'5': '.....',
|
|
211
|
+
'6': '-....',
|
|
212
|
+
'7': '--...',
|
|
213
|
+
'8': '---..',
|
|
214
|
+
'9': '----.',
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
var KidscipherGlyphs_1;
|
|
218
|
+
var hasRequiredKidscipherGlyphs;
|
|
219
|
+
|
|
220
|
+
function requireKidscipherGlyphs () {
|
|
221
|
+
if (hasRequiredKidscipherGlyphs) return KidscipherGlyphs_1;
|
|
222
|
+
hasRequiredKidscipherGlyphs = 1;
|
|
223
|
+
// Auto-generated by generate-font
|
|
224
|
+
const KidscipherGlyphs = Object.freeze({
|
|
225
|
+
POLAND_CROSS_A: '\u{64}',
|
|
226
|
+
POLAND_CROSS_B: '\u{65}',
|
|
227
|
+
POLAND_CROSS_C: '\u{66}',
|
|
228
|
+
POLAND_CROSS_CH: '\u{67}',
|
|
229
|
+
POLAND_CROSS_D: '\u{68}',
|
|
230
|
+
POLAND_CROSS_E: '\u{69}',
|
|
231
|
+
POLAND_CROSS_F: '\u{6a}',
|
|
232
|
+
POLAND_CROSS_G: '\u{6b}',
|
|
233
|
+
POLAND_CROSS_H: '\u{6c}',
|
|
234
|
+
POLAND_CROSS_I: '\u{6d}',
|
|
235
|
+
POLAND_CROSS_J: '\u{6e}',
|
|
236
|
+
POLAND_CROSS_K: '\u{6f}',
|
|
237
|
+
POLAND_CROSS_L: '\u{70}',
|
|
238
|
+
POLAND_CROSS_M: '\u{71}',
|
|
239
|
+
POLAND_CROSS_N: '\u{72}',
|
|
240
|
+
POLAND_CROSS_O: '\u{73}',
|
|
241
|
+
POLAND_CROSS_P: '\u{74}',
|
|
242
|
+
POLAND_CROSS_Q: '\u{75}',
|
|
243
|
+
POLAND_CROSS_R: '\u{76}',
|
|
244
|
+
POLAND_CROSS_S: '\u{77}',
|
|
245
|
+
POLAND_CROSS_T: '\u{78}',
|
|
246
|
+
POLAND_CROSS_U: '\u{79}',
|
|
247
|
+
POLAND_CROSS_V: '\u{7a}',
|
|
248
|
+
POLAND_CROSS_W: '\u{7b}',
|
|
249
|
+
POLAND_CROSS_X: '\u{7c}',
|
|
250
|
+
POLAND_CROSS_Y: '\u{7d}',
|
|
251
|
+
POLAND_CROSS_Z: '\u{7e}'
|
|
252
|
+
});
|
|
253
|
+
KidscipherGlyphs_1 = { KidscipherGlyphs };
|
|
254
|
+
return KidscipherGlyphs_1;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
var KidscipherGlyphsExports = requireKidscipherGlyphs();
|
|
258
|
+
|
|
259
|
+
class PolandCrossCipher extends SubstitutionCipher {
|
|
260
|
+
constructor() {
|
|
261
|
+
super(PolandCrossCipher.POLAND_CROSS_MAP);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
PolandCrossCipher.POLAND_CROSS_MAP = {
|
|
265
|
+
A: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_A,
|
|
266
|
+
B: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_B,
|
|
267
|
+
C: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_C,
|
|
268
|
+
D: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_D,
|
|
269
|
+
E: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_E,
|
|
270
|
+
F: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_F,
|
|
271
|
+
G: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_G,
|
|
272
|
+
H: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_H,
|
|
273
|
+
CH: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_CH,
|
|
274
|
+
I: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_I,
|
|
275
|
+
J: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_J,
|
|
276
|
+
K: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_K,
|
|
277
|
+
L: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_L,
|
|
278
|
+
M: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_M,
|
|
279
|
+
N: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_N,
|
|
280
|
+
O: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_O,
|
|
281
|
+
P: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_P,
|
|
282
|
+
Q: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Q,
|
|
283
|
+
R: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_R,
|
|
284
|
+
S: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_S,
|
|
285
|
+
T: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_T,
|
|
286
|
+
U: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_U,
|
|
287
|
+
V: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_V,
|
|
288
|
+
W: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_W,
|
|
289
|
+
X: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_X,
|
|
290
|
+
Y: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Y,
|
|
291
|
+
Z: KidscipherGlyphsExports.KidscipherGlyphs.POLAND_CROSS_Z,
|
|
292
|
+
};
|
|
293
|
+
|
|
294
|
+
class ShiftCipher extends Cipher {
|
|
295
|
+
constructor(baseAlphabet, rotors) {
|
|
296
|
+
super();
|
|
297
|
+
// Check all alphabets have the same length
|
|
298
|
+
for (const alpha of rotors) {
|
|
299
|
+
if (alpha.length !== baseAlphabet.length) {
|
|
300
|
+
throw new Error('All alphabets must have the same length');
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
this.baseAlphabet = baseAlphabet;
|
|
304
|
+
this.rotors = rotors;
|
|
305
|
+
}
|
|
306
|
+
encodeToken(token, configuration) {
|
|
307
|
+
const { shifts } = configuration;
|
|
308
|
+
let encoded = '';
|
|
309
|
+
if (this.baseAlphabet.includes(token)) {
|
|
310
|
+
const index = this.baseAlphabet.indexOf(token);
|
|
311
|
+
for (let i = 0; i < this.rotors.length; i++) {
|
|
312
|
+
const wheel = this.rotors[i];
|
|
313
|
+
const shiftedIndex = (index + shifts[i]) % wheel.length;
|
|
314
|
+
encoded += wheel[shiftedIndex];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return encoded;
|
|
318
|
+
}
|
|
319
|
+
encode(input, configuration, opts) {
|
|
320
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
321
|
+
input: {
|
|
322
|
+
caseSensitive: false,
|
|
323
|
+
letterSeparator: '',
|
|
324
|
+
wordSeparator: ' ',
|
|
325
|
+
},
|
|
326
|
+
output: {
|
|
327
|
+
casing: 'original',
|
|
328
|
+
letterSeparator: '',
|
|
329
|
+
wordSeparator: ' ',
|
|
330
|
+
},
|
|
331
|
+
});
|
|
332
|
+
return super.encode(input, configuration, mergedOpts);
|
|
333
|
+
}
|
|
334
|
+
decodeToken(token, configuration) {
|
|
335
|
+
const { shifts } = configuration;
|
|
336
|
+
let encoded = '';
|
|
337
|
+
if (token.length === this.rotors.length) {
|
|
338
|
+
let currentIndex = -1;
|
|
339
|
+
for (let i = this.rotors.length - 1; 0 <= i; i--) {
|
|
340
|
+
if (this.rotors[i].includes(token[i])) {
|
|
341
|
+
currentIndex = this.rotors[i].indexOf(token[i]);
|
|
342
|
+
currentIndex =
|
|
343
|
+
(currentIndex - shifts[i] + this.baseAlphabet.length) %
|
|
344
|
+
this.baseAlphabet.length;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
// invalid token
|
|
348
|
+
return '';
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
encoded = this.baseAlphabet[currentIndex];
|
|
352
|
+
}
|
|
353
|
+
return encoded;
|
|
354
|
+
}
|
|
355
|
+
decode(input, configuration, opts) {
|
|
356
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
357
|
+
input: {
|
|
358
|
+
caseSensitive: false,
|
|
359
|
+
letterSeparator: '',
|
|
360
|
+
wordSeparator: ' ',
|
|
361
|
+
},
|
|
362
|
+
output: {
|
|
363
|
+
casing: 'original',
|
|
364
|
+
letterSeparator: '',
|
|
365
|
+
wordSeparator: ' ',
|
|
366
|
+
},
|
|
367
|
+
});
|
|
368
|
+
return super.decode(input, configuration, mergedOpts);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
class ShiftAlphabetCipher extends ShiftCipher {
|
|
373
|
+
constructor(alphabet) {
|
|
374
|
+
if (!alphabet) {
|
|
375
|
+
alphabet = ShiftAlphabetCipher.DEFAULT_ALPHABET;
|
|
376
|
+
}
|
|
377
|
+
super(alphabet, [alphabet]);
|
|
378
|
+
}
|
|
379
|
+
encode(input, { shift }, opts) {
|
|
380
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
381
|
+
input: {
|
|
382
|
+
caseSensitive: false,
|
|
383
|
+
letterSeparator: '',
|
|
384
|
+
wordSeparator: ' ',
|
|
385
|
+
},
|
|
386
|
+
output: {
|
|
387
|
+
casing: 'original',
|
|
388
|
+
letterSeparator: '',
|
|
389
|
+
wordSeparator: ' ',
|
|
390
|
+
},
|
|
391
|
+
});
|
|
392
|
+
return super.encode(input, { shifts: [shift] }, mergedOpts);
|
|
393
|
+
}
|
|
394
|
+
decode(input, { shift }, opts) {
|
|
395
|
+
const mergedOpts = withDefaultCipherOptions(opts, {
|
|
396
|
+
input: {
|
|
397
|
+
caseSensitive: false,
|
|
398
|
+
letterSeparator: '',
|
|
399
|
+
wordSeparator: ' ',
|
|
400
|
+
},
|
|
401
|
+
output: {
|
|
402
|
+
casing: 'original',
|
|
403
|
+
letterSeparator: '',
|
|
404
|
+
wordSeparator: ' ',
|
|
405
|
+
},
|
|
406
|
+
});
|
|
407
|
+
return super.decode(input, { shifts: [shift] }, mergedOpts);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
ShiftAlphabetCipher.DEFAULT_ALPHABET = [
|
|
411
|
+
'A',
|
|
412
|
+
'B',
|
|
413
|
+
'C',
|
|
414
|
+
'D',
|
|
415
|
+
'E',
|
|
416
|
+
'F',
|
|
417
|
+
'G',
|
|
418
|
+
'H',
|
|
419
|
+
'I',
|
|
420
|
+
'J',
|
|
421
|
+
'K',
|
|
422
|
+
'L',
|
|
423
|
+
'M',
|
|
424
|
+
'N',
|
|
425
|
+
'O',
|
|
426
|
+
'P',
|
|
427
|
+
'Q',
|
|
428
|
+
'R',
|
|
429
|
+
'S',
|
|
430
|
+
'T',
|
|
431
|
+
'U',
|
|
432
|
+
'V',
|
|
433
|
+
'W',
|
|
434
|
+
'X',
|
|
435
|
+
'Y',
|
|
436
|
+
'Z',
|
|
437
|
+
];
|
|
438
|
+
|
|
439
|
+
export { MorseCodeCipher, PolandCrossCipher, ShiftAlphabetCipher, SubstitutionCipher };
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CipherOptions } from '../core/cipher-options/CipherOptions';
|
|
2
|
+
export type CipherConfigurationsRecord = Record<string, any>;
|
|
3
|
+
declare abstract class Cipher {
|
|
4
|
+
abstract encodeToken(token: string, configuration?: CipherConfigurationsRecord): string;
|
|
5
|
+
encode(input: string, configuration?: CipherConfigurationsRecord, opts?: CipherOptions): string;
|
|
6
|
+
abstract decodeToken(token: string, configuration?: CipherConfigurationsRecord): string;
|
|
7
|
+
decode(input: string, configuration?: CipherConfigurationsRecord, opts?: CipherOptions): string;
|
|
8
|
+
}
|
|
9
|
+
export default Cipher;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import SubstitutionCipher from '../substitution/SubstitutionCipher';
|
|
2
|
+
import { CipherOptions } from '../../core/cipher-options/CipherOptions';
|
|
3
|
+
import { CipherConfigurationsRecord } from '../Cipher';
|
|
4
|
+
export type MorseCodeCipherOptions = CipherConfigurationsRecord | {
|
|
5
|
+
dotDashMapping?: {
|
|
6
|
+
dot?: string;
|
|
7
|
+
dash?: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
declare class MorseCodeCipher extends SubstitutionCipher {
|
|
11
|
+
static MORSE_CODE_MAP: Record<string, string>;
|
|
12
|
+
constructor();
|
|
13
|
+
encode(input: string, configuration?: MorseCodeCipherOptions, opts?: CipherOptions): string;
|
|
14
|
+
decode(input: string, configuration?: MorseCodeCipherOptions, opts?: CipherOptions): string;
|
|
15
|
+
}
|
|
16
|
+
export default MorseCodeCipher;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CipherOptions } from '../../core/cipher-options/CipherOptions';
|
|
2
|
+
import { CipherConfigurationsRecord } from '../Cipher';
|
|
3
|
+
import ShiftCipher from './ShiftCipher';
|
|
4
|
+
type ShiftAlphabetCipherOptions = CipherConfigurationsRecord | {
|
|
5
|
+
shift: number;
|
|
6
|
+
};
|
|
7
|
+
declare class ShiftAlphabetCipher extends ShiftCipher {
|
|
8
|
+
static DEFAULT_ALPHABET: string[];
|
|
9
|
+
constructor(alphabet?: string[]);
|
|
10
|
+
encode(input: string, { shift }: ShiftAlphabetCipherOptions, opts?: CipherOptions): string;
|
|
11
|
+
decode(input: string, { shift }: ShiftAlphabetCipherOptions, opts?: CipherOptions): string;
|
|
12
|
+
}
|
|
13
|
+
export default ShiftAlphabetCipher;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { CipherOptions } from '../../core/cipher-options/CipherOptions';
|
|
2
|
+
import Cipher, { CipherConfigurationsRecord } from '../Cipher';
|
|
3
|
+
type ShiftCipherOptions = CipherConfigurationsRecord | {
|
|
4
|
+
shifts: number[];
|
|
5
|
+
};
|
|
6
|
+
declare abstract class ShiftCipher extends Cipher {
|
|
7
|
+
private baseAlphabet;
|
|
8
|
+
private rotors;
|
|
9
|
+
constructor(baseAlphabet: string[], rotors: string[][]);
|
|
10
|
+
encodeToken(token: string, configuration: ShiftCipherOptions): string;
|
|
11
|
+
encode(input: string, configuration?: ShiftCipherOptions, opts?: CipherOptions): string;
|
|
12
|
+
decodeToken(token: string, configuration: ShiftCipherOptions): string;
|
|
13
|
+
decode(input: string, configuration?: ShiftCipherOptions, opts?: CipherOptions): string;
|
|
14
|
+
}
|
|
15
|
+
export default ShiftCipher;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import Cipher from '../Cipher';
|
|
2
|
+
declare class SubstitutionCipher extends Cipher {
|
|
3
|
+
protected encodeMap: Record<string, string>;
|
|
4
|
+
protected decodeMap: Record<string, string>;
|
|
5
|
+
constructor(encodeMap: Record<string, string>);
|
|
6
|
+
encodeToken(token: string): string;
|
|
7
|
+
decodeToken(token: string): string;
|
|
8
|
+
}
|
|
9
|
+
export default SubstitutionCipher;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { CasingOptions } from "./CipherOptions";
|
|
2
|
+
export type TextProcessor = (text: string) => string;
|
|
3
|
+
declare const Processor: {
|
|
4
|
+
ignoreCasingSensitive: (caseSensitive?: boolean) => TextProcessor;
|
|
5
|
+
casing: (casingOption: CasingOptions) => TextProcessor;
|
|
6
|
+
};
|
|
7
|
+
export default Processor;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { KidscipherGlyphs } from './fonts/KidscipherGlyphs';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import './styles.css';
|
|
2
|
+
export { default as SubstitutionCipher } from './cipher/substitution/SubstitutionCipher';
|
|
3
|
+
export { default as MorseCodeCipher } from './cipher/morsecode/MorseCodeCipher';
|
|
4
|
+
export { default as PolandCrossCipher } from './cipher/cross/poland/PolandCrossCipher';
|
|
5
|
+
export { default as ShiftAlphabetCipher } from './cipher/shift/ShiftAlphabetCipher';
|
package/package.json
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kidscipher",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"homepage": "https://github.com/fandau1/kidscipher",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"types": "dist/types/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.esm.js",
|
|
11
|
+
"require": "./dist/index.cjs.js"
|
|
12
|
+
},
|
|
13
|
+
"./font": {
|
|
14
|
+
"import": "./dist/font.esm.js",
|
|
15
|
+
"require": "./dist/font.cjs.js"
|
|
16
|
+
},
|
|
17
|
+
"./kidscipher.css": "./dist/kidscipher.css"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "rollup -c",
|
|
21
|
+
"test": "vitest",
|
|
22
|
+
"generate-font-svg": "node scripts/generate_font/generate_svg/index.js",
|
|
23
|
+
"generate-font": "node scripts/generate_font/index.js",
|
|
24
|
+
"prebuild-fonts": "npm run generate-font-svg && npm run generate-font"
|
|
25
|
+
},
|
|
26
|
+
"files": [
|
|
27
|
+
"dist/**/*"
|
|
28
|
+
],
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@eslint/js": "^9.35.0",
|
|
31
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
32
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
33
|
+
"@rollup/plugin-url": "^8.0.2",
|
|
34
|
+
"@types/node": "^24.3.1",
|
|
35
|
+
"@typescript-eslint/eslint-plugin": "^8.42.0",
|
|
36
|
+
"@typescript-eslint/parser": "^8.42.0",
|
|
37
|
+
"eslint": "^9.35.0",
|
|
38
|
+
"eslint-config-prettier": "^10.1.8",
|
|
39
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
40
|
+
"prettier": "^3.6.2",
|
|
41
|
+
"rollup": "^4.50.0",
|
|
42
|
+
"rollup-plugin-postcss": "^4.0.2",
|
|
43
|
+
"rollup-plugin-typescript2": "^0.36.0",
|
|
44
|
+
"svg2ttf": "^6.0.3",
|
|
45
|
+
"svgicons2svgfont": "^15.0.1",
|
|
46
|
+
"ttf2woff": "^3.0.0",
|
|
47
|
+
"ttf2woff2": "^8.0.0",
|
|
48
|
+
"typescript": "^5.9.2",
|
|
49
|
+
"vitest": "^3.2.4"
|
|
50
|
+
}
|
|
51
|
+
}
|