Last active
March 4, 2025 12:14
-
-
Save FrostBird347/e7c017d096b3b50a75f5dcd5b4d08b99 to your computer and use it in GitHub Desktop.
Scream Cipher
This file contains hidden or 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
// https://xkcd.com/3054/ | |
function scream(input, padChars = false) { | |
let keyE = { | |
"A": "A", | |
"B": "Ȧ", | |
"C": "A̧", | |
"D": "A̠", | |
"E": "Á", | |
"F": "A̮", | |
"G": "A̋", | |
"H": "A̰", | |
"I": "Ả", | |
"J": "A̓", | |
"K": "Ạ", | |
"L": "Ă", | |
"M": "Ǎ", | |
"N": "Â", | |
"O": "Å", | |
"P": "A̯", | |
"Q": "A̤", | |
"R": "Ȃ", | |
"S": "Ã", | |
"T": "Ā", //Wasn't sure if it was 'Ā' or 'A̅' so I just copied Ā from the panel's hover text | |
"U": "Ä", | |
"V": "À", | |
"W": "Ȁ", | |
"X": "A̽", | |
"Y": "A̦", | |
"Z": "A̷" //Could be 'A̸' or 'A̷', im guessing it's A̷ | |
}; | |
let keyD = { | |
//Add those uncertain keys to the decoder | |
"A̸": "Z", | |
"A̅": "T", | |
//Add decoding support for some other implementations that avoid combining characters (even though they are used in the panel's hover text) | |
"Ȧ": "B", | |
"Á": "E", | |
"Ả": "I", | |
"Ạ": "K", | |
"Ă": "L", | |
"Ǎ": "M", | |
"Â": "N", | |
"Å": "O", | |
"Ȃ": "R", | |
"Ã": "S", | |
"Ā": "T", | |
"Ä": "U", | |
"À": "V", | |
"Ȁ": "W", | |
"Ⱥ": "Z", | |
//Have seen some other people also use these characters instead | |
"A̱": "D", | |
"A̲": "D", | |
"Aͯ": "X", | |
"A̡": "C" | |
}; | |
//Use the encoder key to fill out the rest of the decoder key | |
for (let i = 0, tmp = Object.keys(keyE); i < tmp.length; i++) { | |
keyD[keyE[tmp[i]]] = tmp[i]; | |
//This seems to slightly improve the chances of an encoded message not getting obliterated when sent in discord | |
if (padChars && tmp[i] != "A") { | |
keyE[tmp[i]] += ''; | |
} | |
} | |
//Too lazy to check if it should be encoded or decoded so we just do both | |
let eOut = ""; | |
let dOut = ""; | |
let splitIn = input.toUpperCase().split(""); | |
for (let i = 0; i < splitIn.length; i++) { | |
//If input is in dictionary add value, otherwise add input | |
eOut += (keyE[splitIn[i]] != undefined) ? keyE[splitIn[i]] : splitIn[i]; | |
//If the input is 'A' then we need to check the next character before assuming it's just an 'A' | |
if (splitIn[i] == "A") { | |
let tmp = splitIn[i] + splitIn[i + 1]; | |
if (keyD[tmp] != undefined) { | |
dOut += keyD[tmp]; | |
//Increment the index by 1 to skip over the combining character on the next loop | |
i++; | |
//But make sure the skipped char is still encoded to prevent a message from being corrupted if it's encoded a second time | |
eOut += (keyE[splitIn[i]] != undefined) ? keyE[splitIn[i]] : splitIn[i]; | |
} else { | |
dOut += "A"; | |
} | |
} else { | |
dOut += (keyD[splitIn[i]] != undefined) ? keyD[splitIn[i]] : splitIn[i]; | |
} | |
} | |
return {encoded: eOut, decoded: dOut}; | |
} | |
console.log("scream.js loaded, use scream(\"input\") in your code!\nwritten by FrostBird347, licensed under MIT"); | |
console.log(scream("test message").encoded); | |
console.log(scream("ĀÁÃĀ ǍÁÃÃAA̋Á").decoded); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example page: https://frostbird347.bitbucket.io/db/scream.js