Created
June 23, 2017 04:53
-
-
Save impiaaa/bc3377106a8bda51f4d8d3c995fcce6d to your computer and use it in GitHub Desktop.
Unicode homoglyph secret message encoder/decoder
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
ᅟᅠ ㅤ | |
!ǃ! | |
"″" | |
$$ | |
%% | |
&& | |
'' | |
(﹝( | |
)﹞) | |
*⁎* | |
++ | |
,‚, | |
-‐- | |
.٠․‧。.。 | |
/ ̸⁄∕╱⫻⫽/ノ | |
0OoΟοОоՕOo | |
1Iا1 | |
22 | |
33 | |
44 | |
55 | |
66 | |
77 | |
8Ց8 | |
99 | |
:։܃܄∶꞉: | |
;;; | |
>›> | |
?? | |
@@ | |
[[ | |
\\ | |
]] | |
^^ | |
__ | |
`` | |
AÀÁÂÃÄÅΑᎪA | |
aàáâãäåɑαаa | |
BßʙΒβВᏴᛒB | |
bЬb | |
CϹСᏟⅭC | |
cϲсⅽc | |
DĎĐᎠⅮD | |
dďđԁժⅾd | |
EÈÉÊËĒĔĖĘĚΕЕᎬE | |
eéêëēĕėěеe | |
FϜF | |
ff | |
GɢԌնᏀG | |
gɡg | |
HʜΗНᎻH | |
hһh | |
IlΙІاᛁⅠI | |
iɩіᎥⅰi | |
JЈᎫJ | |
jϳјյj | |
KΚКᏦᛕKK | |
kκk | |
LʟᏞⅬL | |
lιاⅼl | |
MΜϺМᎷᛖⅯM | |
mⅿm | |
NɴΝN | |
nn | |
O0ΟОՕO | |
oοоo | |
PΡРᏢP | |
pρрp | |
QႭႳQ | |
qq | |
RʀᏒᚱR | |
rԻr | |
SЅՏႽᏚS | |
sѕs | |
TΤТᎢT | |
tτt | |
UԱՍ⋃U | |
uμυu | |
VѴᏙⅤⅴVv | |
vνѵ | |
WᎳW | |
wѡw | |
XΧХⅩX | |
xχхⅹx | |
YʏΥҮY | |
yγуy | |
ZΖᏃZ | |
zz | |
{{ | |
|ǀا| | |
}} | |
~⁓~ | |
ßӧ | |
ÄӒ | |
ÖӦ |
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
#!/usr/bin/env python3 | |
import random | |
from functools import reduce | |
BIT_WIDTH = 5 | |
CHAR_OFFSET = 65 | |
f = open("homoglyphs.txt") | |
latinToHomoglyphs = {line[0]: line[1:-1] for line in f} | |
f.close() | |
def isHomoglyph(a): | |
return a not in latinToHomoglyphs | |
def encode(message, secret): | |
secret = secret.upper() | |
assert len(message) >= len(secret)*BIT_WIDTH | |
messageIndex = 0 | |
encoded = "" | |
for c in secret: | |
code = ord(c)-CHAR_OFFSET | |
for i in range(BIT_WIDTH): | |
if (code>>((BIT_WIDTH-1)-i))&1: encoded += random.choice(latinToHomoglyphs[message[messageIndex]]) | |
else: encoded += message[messageIndex] | |
messageIndex += 1 | |
while messageIndex < len(message): | |
encoded += message[messageIndex] | |
messageIndex += 1 | |
return encoded | |
def decode(encoded): | |
decoded = "" | |
for messageIndex in range(0, len(encoded), BIT_WIDTH): | |
chars = encoded[messageIndex:messageIndex+BIT_WIDTH] | |
charsAreHomoglyph = map(isHomoglyph, chars) | |
code = reduce(lambda a, b: a|b, [int(x)<<((BIT_WIDTH-1)-i) for i, x in enumerate(charsAreHomoglyph)]) | |
decoded += chr(code+CHAR_OFFSET) | |
return decoded | |
if __name__ == "__main__": | |
import sys | |
if len(sys.argv) <= 2: | |
print("Usage: {} [encode|decode] message [secret]".format(sys.argv[0]), file=sys.stderr) | |
elif sys.argv[1] == "encode": | |
print(encode(sys.argv[2], sys.argv[3])) | |
elif sys.argv[1] == "decode": | |
print(decode(sys.argv[2])) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment