-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
271 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
# Morse | ||
|
||
> Morse code transforms a message using short and long impulses. It was | ||
one of the first telecommunication codes invented. | ||
|
||
## Cipher behavior information | ||
|
||
* Case sensitive? ❌ | ||
* Alphabet: `ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 .,:;?-_()'=+/@` | ||
* Characters not in alphabet will be: **preserved**, **omitted** or **throwing an error (default)** | ||
|
||
## Default options object | ||
|
||
The options are the same for both methods, `encode` and `decode` | ||
|
||
``` | ||
const options = { | ||
separator: ' ', // Custom delimiter or glue | ||
failOnUnknownCharacter: true, // Should an error be thrown when a character is not included in the alphabet | ||
ommitUnknownCharacter: false // Should unknown character be ommitted or preserverd? (Only if failOnUnknownCharacter is false) | ||
} | ||
``` | ||
|
||
## Usage | ||
|
||
### Encoding | ||
|
||
#### Default | ||
|
||
``` | ||
// Direct import if you need encode and decode | ||
import { morse } from 'cipher-collection' | ||
// morse.encode()/morse.decoode() | ||
// Alternative | ||
import { encode } from 'cipher-collection/morse' | ||
console.log(encode('SOS')) // ... --- ... | ||
``` | ||
|
||
#### With custom glue | ||
|
||
``` | ||
import { encode } from 'cipher-collection/morse' | ||
const options = { separator: '~' } | ||
console.log(encode('SOS', options)) // ...~---~... | ||
``` | ||
|
||
#### Without error throwing | ||
|
||
There are **two options** when disabling errors: | ||
|
||
``` | ||
import { encode } from 'cipher-collection/morse' | ||
const preserveOptions = { | ||
separator: '', | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: false | ||
} | ||
// Preserve chraracters that can't get encoded | ||
console.log(encode('€€€', preserveOptions)) // €€€ | ||
const ommitOptions = { | ||
separator: '', | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: true | ||
} | ||
// Ommit chraracters that can't get encoded | ||
console.log(encode('€€€S', ommitOptions)) // ... | ||
``` | ||
|
||
|
||
### Decoding | ||
|
||
#### Default | ||
|
||
``` | ||
import { decode } from 'cipher-collection/morse' | ||
console.log(decode('... --- ...')) // SOS | ||
``` | ||
|
||
#### With custom delimiter | ||
|
||
``` | ||
import { decode } from 'cipher-collection/morse' | ||
const options = { separator: '~' } | ||
console.log(decode('...~---~...', options)) // SOS | ||
``` | ||
|
||
#### Without error throwing | ||
|
||
Similar to `encode`, there are **two options** when disabling errors: | ||
|
||
``` | ||
import { decode } from 'cipher-collection/morse' | ||
const preserveOptions = { | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: false | ||
} | ||
// Preserve chraracters that can't get decoded | ||
console.log(decode('.-.-.-.-.-', preserveOptions)) // .-.-.-.-.- | ||
const ommitOptions = { | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: true | ||
} | ||
// Ommit chraracters that can't get decoded | ||
console.log(decode('.-.-.-.-.- ...', ommitOptions)) // S | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
export const decode = (input, options = {}) => { | ||
options = { ...DEFAULT_OPTIONS, ...options } | ||
return input.split(options.separator).map(c => { | ||
const decodedCharacter = Object.entries(ALPHABET).find(([k, v]) => v === c) | ||
|
||
if (decodedCharacter) { | ||
return decodedCharacter[0] | ||
} | ||
if (options.failOnUnknownCharacter) { | ||
throw Error('Undecodable character') | ||
} | ||
return options.ommitUnknownCharacter ? '' : c | ||
}).join('') | ||
} | ||
|
||
export const encode = (input, options = {}) => { | ||
options = { ...DEFAULT_OPTIONS, ...options } | ||
|
||
return [...input.toUpperCase()].map(c => { | ||
const encodedCharacter = Object.entries(ALPHABET).find(([k]) => k === c) | ||
|
||
if (encodedCharacter) { | ||
return encodedCharacter[1] | ||
} | ||
if (options.failOnUnknownCharacter) { | ||
throw Error('Unencodable character') | ||
} | ||
return options.ommitUnknownCharacter ? '' : c | ||
}).join(options.separator) | ||
} | ||
|
||
const ALPHABET = { | ||
A: '.-', | ||
B: '-...', | ||
C: '-.-.', | ||
D: '-..', | ||
E: '.', | ||
F: '..-.', | ||
G: '--.', | ||
H: '....', | ||
I: '..', | ||
J: '.---', | ||
K: '-.-', | ||
L: '.-..', | ||
M: '--', | ||
N: '-.', | ||
O: '---', | ||
P: '.--.', | ||
Q: '--.-', | ||
R: '.-.', | ||
S: '...', | ||
T: '-', | ||
U: '..-', | ||
V: '...-', | ||
W: '.--', | ||
X: '-..-', | ||
Y: '-.--', | ||
Z: '--..', | ||
1: '.----', | ||
2: '..---', | ||
3: '...--', | ||
4: '....-', | ||
5: '.....', | ||
6: '-....', | ||
7: '--...', | ||
8: '---..', | ||
9: '----.', | ||
0: '-----', | ||
' ': '/', | ||
'.': '.-.-.-', | ||
',': '--..--', | ||
':': '---...', | ||
';': '-.-.-.', | ||
'?': '..--..', | ||
'-': '-....-', | ||
'_': '..--.-', | ||
'(': '-.--.', | ||
')': '-.--.-', | ||
'\'': '.----.', | ||
'=': '-...-', | ||
'+': '.-.-.', | ||
'/': '-..-.', | ||
'@': '.--.-.' | ||
} | ||
|
||
const DEFAULT_OPTIONS = { | ||
separator: ' ', | ||
failOnUnknownCharacter: true, | ||
ommitUnknownCharacter: false | ||
} | ||
export default { | ||
decode, | ||
encode | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
import morse from 'morse' | ||
|
||
const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 .,:;?-_()\'=+/@' | ||
const encodedAlphabet = '.- -... -.-. -.. . ..-. --. .... .. .--- -.- .-.. -- -. --- .--. --.- .-. ... - ..- ...- .--' + | ||
' -..- -.-- --.. .---- ..--- ...-- ....- ..... -.... --... ---.. ----. ----- / .-.-.- --..-- ---... -.-.-.' + | ||
' ..--.. -....- ..--.- -.--. -.--.- .----. -...- .-.-. -..-. .--.-.' | ||
const invalidCharacter = { | ||
input: '€S', | ||
preserve: '€...', | ||
ommit: '...' | ||
} | ||
const invalidMorseCharacter = { | ||
input: '.-.-.-.-.-.- ...', | ||
preserve: '.-.-.-.-.-.-S', | ||
ommit: 'S' | ||
} | ||
|
||
describe('decoding', () => { | ||
test('decoding the alphabet', () => { | ||
expect(morse.decode(encodedAlphabet)).toBe(alphabet) | ||
}) | ||
|
||
test('decoding with alternative delimiter', () => { | ||
expect(morse.decode('..._---_...', { | ||
separator: '_' | ||
})).toBe('SOS') | ||
}) | ||
|
||
test('decoding invalid character', () => { | ||
expect(() => { morse.decode(invalidMorseCharacter.input) }).toThrowError('Undecodable character') | ||
expect(morse.decode(invalidMorseCharacter.input, { | ||
failOnUnknownCharacter: false | ||
})).toBe(invalidMorseCharacter.preserve) | ||
expect(morse.decode(invalidMorseCharacter.input, { | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: true | ||
})).toBe(invalidMorseCharacter.ommit) | ||
}) | ||
}) | ||
describe('encoding', () => { | ||
test('encoding the alphabet', () => { | ||
expect(morse.encode(alphabet)).toBe(encodedAlphabet) | ||
}) | ||
test('encoding invalid character', () => { | ||
expect(() => { morse.encode(invalidCharacter.input) }).toThrowError('Unencodable character') | ||
expect(morse.encode(invalidCharacter.input, { | ||
separator: '', | ||
failOnUnknownCharacter: false | ||
})).toBe(invalidCharacter.preserve) | ||
expect(morse.encode(invalidCharacter.input, { | ||
separator: '', | ||
failOnUnknownCharacter: false, | ||
ommitUnknownCharacter: true | ||
})).toBe(invalidCharacter.ommit) | ||
}) | ||
}) |