#!/usr/bin/python """ A python bubble-babble generator, inspired by <http://woozle.org/t/bubblebabble.c>. Here are the original Perl bubble-babble examples, for doctests: >>> babble('432cc46b5c67c9adaabdcc6c69e23d6d'.decode('hex')) 'xibod-sycik-rilak-lydap-tipur-tifyk-sipuv-dazok-tixox' >>> babble('5a1edbe07020525fd28cba1ea3b76694'.decode('hex')) 'xikic-vikyv-besed-begyh-zagim-sevic-vomer-lunon-gexex' >>> babble('1c453603cdc914c1f2eeb1abddae2e03'.decode('hex')) 'xelag-hatyb-fafes-nehys-cysyv-vasop-rylop-vorab-fuxux' >>> babble('df8ec33d78ae78280e10873f5e58d5ad'.decode('hex')) 'xulom-vebyf-tevyp-vevid-mufic-bucef-zylyh-mehyp-tuxax' >>> babble('02b682a73739a9fb062370eaa8bcaec9'.decode('hex')) 'xebir-kybyp-latif-napoz-ricid-fusiv-popir-soras-nixyx' """ import itertools consonants = "bcdfghklmnprstvz" vowels = "aeiouy" def maybe_ord(x): """If x is a string of length 1, return the ascii value. If it's a longer string, return an iterator of values. Otherwise, coerce it to an int() >>> maybe_ord('A') 65 >>> tuple(maybe_ord('lol')) (108, 111, 108) >>> maybe_ord(242) 242 >>> maybe_ord(242.2222) 242 """ try: if len(x) is 1 and len(x[0]) is 1: return ord(x) else: return itertools.imap(maybe_ord, x) except: return int(x) def babble(digest, seed=1): """ Compute bubble babble for input buffer. >>> babble('') 'xexax' >>> babble('1234567890') 'xesef-disof-gytuf-katof-movif-baxux' >>> babble('Pineapple') 'xigak-nyryk-humil-bosek-sonax' >>> babble('lol') 'xirak-zorex' >>> import hashlib >>> babble(hashlib.sha1('lol').digest()) 'xibaf-nanob-fyzib-bikyh-davot-zotos-ryzah-decir-lucus-donoz-poxex' >>> babble([70, 85, 129, 199]) 'xicih-habes-laxex' >>> babble(0) 'xebax' """ ret = 'x' x = y = None iters = [maybe_ord(digest)] * 2 for x,y in itertools.izip_longest(fillvalue=None, *iters): ret += vowels[(((x >> 6) & 3) + seed) % 6] ret += consonants[(x >> 2) & 15] ret += vowels[((x & 3) + (seed / 6)) % 6] if y is not None: seed = ((seed * 5) + (x * 7) + y) % 36 ret += consonants[(y >> 4) & 15] ret += '-' ret += consonants[y & 15] if y is not None or x is None: ret += vowels[seed % 6] + 'x' + vowels[seed / 6] return ret + 'x' if __name__ == '__main__': import doctest doctest.testmod()