Esempio n. 1
0
def plotFreq(ciph):
    ciph = Format.keepOnly(ciph.lower(), ALPH)
    fig, ax = plt.subplots(figsize=(10, 5))
    barwidth = 0.3

    lettcounts = [FreqAnalysis.englishProbabilities.get(x, 0) for x in ALPH]
    ciphprobs = FreqAnalysis.getFrequencies(ciph)

    lettplot = []
    for x in range(26):
        lettplot.append(x - (barwidth / 2))
    ax.bar(lettplot, lettcounts, width=barwidth, label="English", color="r")
    try:
        ciphcounts = [ciphprobs.get(x, 0) / len(ciph) for x in ALPH]
        ciphplot = []
        for x in range(26):
            ciphplot.append(x + (barwidth / 2))
        ax.bar(ciphplot, ciphcounts, width=barwidth, label="Cipher Text", color="b")
    except ZeroDivisionError:
        pass
    ax.get_yaxis().set_visible(False)
    ax.set_xticks(range(26))
    ax.set_xticklabels(ALPH.upper())
    ax.legend()

    output = io.BytesIO()
    FigureCanvas(fig).print_png(output)
    return Response(output.getvalue(), mimetype="image/png")
Esempio n. 2
0
def addForwards(text):
    """Insert spacing into text."""

    with open("static/txt/wordlist.txt", encoding="utf-8") as f:
        wordset = set(f.read().split("\n"))

    string = Format.keepOnly(text, ALPH)

    result = []
    maxLen = DetectEnglish.getLongest()

    x = maxLen
    while True:
        word = string[:x]
        if word in wordset:
            result.append(word)
            string = string[x::]
            x = maxLen
        else:
            x -= 1

        if x == 0 and string:
            result.append(string[0])
            string = string[1::]
            x = maxLen
        elif not string:
            break

    return " ".join(result)
Esempio n. 3
0
def decrypt(ciph):
    """Use a hill-climbing algorithm to decipher a substituted alphabet."""

    ciph = Format.keepOnly(ciph.lower(), ALPH)
    if not ciph:
        return ciph, {x: "" for x in ALPH}

    key = [
        x[0] for x in FreqAnalysis.getFrequencies(ciph).most_common()
        if x[0] in ALPH
    ]
    keyMap = dict(zip(key, letterProbs))

    bestKey = []
    bestScore = 0
    i = 0
    while i < 1000:
        result = sub(ciph, keyMap)
        score = DetectEnglish.detect(result)
        if score > bestScore:
            bestScore = score
            bestKey = list(key)
            i = 0
        x = random.randint(1, len(key) - 1)
        y = random.randint(1, len(key) - 1)
        key = list(bestKey)
        key[x], key[y] = bestKey[y], bestKey[x]

        keyMap = dict(zip(key, letterProbs))
        i += 1
    bestMap = dict(zip(key, letterProbs))
    result = sub(ciph, bestMap)
    return result, bestMap
Esempio n. 4
0
def chiSquared(text):
    """Calculate the Chi-Squared statistic of a piece of text."""

    if not text:
        return 0
    text = Format.keepOnly(text.lower(), ALPH)
    count = {x: text.count(x) for x in letterProbs}
    predict = {x[0]: letterProbs.get(x[0], 0) * len(text) for x in count}
    return sum([((count[x] - predict[x])**2) / predict[x]
                for x in letterProbs])
Esempio n. 5
0
def indexOfCoincidence(text):
    """Calculate the Index of Coincidence of a piece of text."""

    if len(text) == 1:
        return 0
    text = Format.keepOnly(text.lower(), ALPH)
    count = FreqAnalysis.getFrequencies(text).most_common()
    ic = sum([(x[1] * (x[1] - 1)) / (len(text) * (len(text) - 1))
              for x in count])
    return ic
Esempio n. 6
0
def decryptWithSubstitution(ciph):
    """Decrypt a general polyalphabetic substitution cipher using mulitple simultaneous hill-climbing algorithms."""

    ciph = Format.keepOnly(ciph.lower(), ALPH)
    length = len(ciph)

    subs = []
    for x in range(0, 7):
        substring = ciph[x::7]
        key = [y[0] for y in FreqAnalysis.getFrequencies(substring).most_common() if y[0] in ALPH]
        for char in letterProbs:
            if char not in key:
                key.append(char)
        subs.append((substring, key))

    i = 0
    bestScore = 0
    result = []
    for sub in subs:
        keyMap = dict(zip(sub[1], letterProbs))
        result.append(Substitution.sub(sub[0], keyMap))
    result = "".join("".join(b) for b in zip_longest(*result, fillvalue=""))
    bestScore = DetectEnglish.detect(result, length=length)

    while i < 10000:
        x = random.randint(0, len(subs) - 1)
        y = random.randint(1, len(subs[x][1]) - 1)
        z = random.randint(1, len(subs[x][1]) - 1)
        subs[x][1][y], subs[x][1][z] = subs[x][1][z], subs[x][1][y]
        result = []
        for sub in subs:
            keyMap = dict(zip(sub[1], letterProbs))
            result.append(Substitution.sub(sub[0], keyMap))
        result = "".join("".join(b) for b in zip_longest(*result, fillvalue=""))
        score = DetectEnglish.detect(result, length=length)
        if score > bestScore:
            bestScore = score
            i = 0
        else:
            subs[x][1][y], subs[x][1][z] = subs[x][1][z], subs[x][1][y]
        i += 1

    result = []
    for sub in subs:
        keyMap = dict(zip(sub[1], letterProbs))
        key = ""
        for x in ALPH:
            for k, v in keyMap.items():
                if k == x:
                    key += v
        result.append(Substitution.sub(sub[0], keyMap))
    result = "".join("".join(b) for b in zip_longest(*result, fillvalue=""))

    return result
Esempio n. 7
0
def find(word):
    """Find anagrams of a given word."""

    with open("static/txt/wordlist.txt", encoding="utf-8") as f:
        wordset = f.read().split("\n")

    word = Format.keepOnly(word.lower(), ALPH)

    anagrams = []
    pattern = sorted(word)
    for x in wordset:
        if sorted(x) == pattern:
            anagrams.append(x)
    anagrams.sort()

    return anagrams
Esempio n. 8
0
def decrypt(ciph, keylen=0, key=""):
    """
    Attempt decryption of the transposition-enciphered text.

    One of keylen or key is required to function.
    """

    if not (key or keylen):
        return "", ""

    ciph = Format.keepOnly(ciph.lower(), ALPH, NUMS)
    text = _process(ciph, keylen=keylen, key=key)

    if key:
        return _decryptWithKey(text, key.split(","))
    if keylen < 9:
        bestResult, bestKey = _decryptShortKey(text)
    else:
        bestResult, bestKey = _decryptLongKey(text, keylen)

    bestScore = DetectEnglish.detectWord(SpaceAdd.addLongest(bestResult))

    text = _process(ciph, keylen=len(ciph) // keylen, key=key)
    text = "".join(text)
    text = _process(text, keylen=keylen, key=key)
    if keylen < 9:
        result, key = _decryptShortKey(text)
    else:
        result, key = _decryptLongKey(text, keylen)
    score = DetectEnglish.detectWord(SpaceAdd.addLongest(result))
    if score > bestScore:
        bestResult = result
        bestKey = key

    overflow = len(ciph) % keylen
    if overflow != 0:
        bestScore = 0
        lastset = bestResult[-overflow:]
        overflow = len(lastset)
        for perm in itertools.permutations(lastset, overflow):
            result = bestResult[:-overflow] + "".join(perm)
            score = DetectEnglish.detectWord(SpaceAdd.addLongest(result))
            if score > bestScore:
                bestScore = score
                bestResult = result

    return bestResult, bestKey, bestScore
Esempio n. 9
0
def subInputs():
    if request.method == "POST":
        changed = request.json["name"][0]
        newval = request.json["val"].lower()
        if newval == "":
            newval = "_"
        ciphText = Format.keepOnly(request.json["ciph"].lower(), ALPH)
        plainText = Format.remove(request.json["plain"], SPACE).lower()
        if plainText == "":
            new = ''.join([newval if x in changed else "_" for x in ciphText])
        else:
            plainText = [x for x in plainText]
            for i, letter in enumerate(ciphText):
                if letter == changed:
                    plainText[i] = newval
            new = "".join(plainText)
        score = DetectEnglish.detectWord(SpaceAdd.add(new)) * 100
        return json.dumps({"plain": new, "score": f"{score}% certainty"})
    return "error"
Esempio n. 10
0
def addLongest(text):
    """Insert spacing into text. Longest identified words inserted first."""

    with open("static/txt/wordlist.txt", encoding="utf-8") as f:
        wordset = set(f.read().split("\n"))

    string = Format.keepOnly(text, ALPH)

    result = [""] * len(string)
    maxLen = DetectEnglish.getLongest()

    for chunkSize in range(maxLen, 0, -1):
        for i in range(0, len(string) - chunkSize + 1):
            if string[i:i + chunkSize] in wordset:
                result[i] = string[i:i + chunkSize]
                string = string.replace(string[i:i + chunkSize],
                                        "." * chunkSize)

    result = filter(lambda x: x != "", result)

    return " ".join(result)
Esempio n. 11
0
def decrypt(ciph, key="", keylen=0):
    """Automatically decrypt a vigenere cipher using the Index of Coincidence to find possible key lengths."""

    ciph = Format.keepOnly(ciph.lower(), ALPH)

    if key:
        return decryptWithKey(ciph, key)
    if keylen:
        return decryptWithKeylen(ciph, int(keylen))

    sub = {}
    for i in range(2, 26):
        sub[i] = []
        for j in range(i):
            sub[i].append(ciph[j::i])

    ic = {}
    for i in sub:
        avgic = sum(map(DetectEnglish.indexOfCoincidence, sub[i])) / i
        if avgic > 0.06:
            ic[i] = avgic

    bestKey = ""
    bestScore = 0
    bestResult = ""
    for i in ic:
        results = []
        key = []
        for x in sub[i]:
            result, shift = Caesar.decrypt(x)
            results.append(result)
            key.append(shift)
        result = Transposition.recreate(results)
        score = DetectEnglish.detect(result)
        if score > bestScore:
            bestScore = score
            bestKey = "".join(key)
            bestResult = result

    return bestResult, ",".join(bestKey), bestScore
Esempio n. 12
0
def splitKey():
    if request.method == "POST":
        key = Format.keepOnly(request.json["key"].lower(), ALPH)
        key = ",".join([x for x in key])
        return json.dumps({"key": key})
    return "error"