Hacker News new | ask | show | jobs
by somat 465 days ago
I got nerd sniped by a recent xkcd.

https://xkcd.com/3054/ (the scream cypher)

And halfway through implementing it. I realized that these combining characters will attach to any letter, and it would be easy to have crappy stegonography on top of your crappy ceaser cypher.

Probably nothing new, but I had fun.

D̊o̝ n̝o̊ť f̔o͞r̊g̝e͞t̍ t̊h̠e̗ milk

    import string
    
    def combine_list():
            l = []
            for c in range(0x0300, 0x0370):
                    if c != 0x340f: #non joiner mark
                            l.append(chr(c))
                    #print(str(c), 'A' + chr(c))
            return l
    
    class codebook_a():
            def __init__(self):
                    self.cb = dict(zip(string.printable, combine_list()))
                    self.cb[''] = ''
                    self.d = {}
                    for c in self.cb:
                            self.d[self.cb[c]] = c
            def encode(self, message, fake):
                    if len(message) > len(fake):
                            raise ValueError('fake must be longer than message')
                    ml = list(message)
                    fl = list(fake)
                    encode = []
                    while fl:
                            c = fl.pop(0)
                            if c != ' ':
                                    if ml:
                                            m = ml.pop(0)
                                    else:
                                            m = ''
                                    encode.append(c + self.cb[m])
                            else:
                                    encode.append(c)  
                    return ''.join(encode)
            def decode(self, message):
                    plain = []
                    for c in message:
                            p = self.d.get(c)
                            if p is not None:
                                    plain.append(p)
                    return ''.join(plain)
    def cli(args):
            cb = codebook_a()
            #check for coded text
            if len(args) == 0:
                    print('message fake : two args')
                    print('a message with no combining charactors(dicritics) will be coded onto fake')
                    print('with combining charactors will extract the real message')
                    return 1
            m = args[0]
            for c in m:
                    if cb.d.get(c):
                            print('decode')
                            print(cb.decode(m))
                            return 0
            print('encode')
            print(cb.encode(m, args[1]))

    if __name__ == '__main__':
            import sys
            cli(sys.argv[1:])