Detect single character XOR

See http://cryptopals.com/sets/1/challenges/4


In [ ]:
function englishiness(ptarray::Array{UInt8, 1})
EnglishFrequencies = Dict( # from http://scottbryce.com/cryptograms/stats.htm
    'e'=>12.51, 
    't'=>9.25,
    'a'=>8.04,
    'o'=>7.6,
    'i'=>7.26,
    'n'=>7.09,
    's'=>6.54,
    'r'=>6.12,
    'h'=>5.49,
    'l'=>4.14,
    'd'=>3.99,
    'c'=>3.06,
    'u'=>2.71,
    'm'=>2.53,
    'f'=>2.3,
    'p'=>2.0,
    'g'=>1.96,
    'w'=>1.92,
    'y'=>1.73,
    'b'=>1.54,
    'v'=>0.99,
    'k'=>0.67,
    'x'=>0.19,
    'j'=>0.16,
    'q'=>0.11,
    'z'=>0.09,
    )
    s=0
    for ll in ptarray
        llchar = Char(ll)
        if isalpha(llchar)
            s+=get(EnglishFrequencies, lowercase(llchar), -5)
        else
            s+=-20
        end
    end
    return s
end
function genBestSingleByteXORDecrypt(ctbytes::Array{UInt8, 1})
    bestdecrypt = []
    bestscore = -Inf
    bestkey = 0x00
    for xx in 0x00:0xff
        if isascii(Char(xx))
            ptbytes = ctbytes $ xx
            ptscore = englishiness(ptbytes)
            if ptscore > bestscore
                bestscore = ptscore
                bestdecrypt = ptbytes
                bestkey = xx
            end
        end
    end
    return (bestscore, bestdecrypt, bestkey)
end;

In [ ]:
bestscore = -Inf
bestdecrypt = []
bestkey = []
for cl in eachline("4.txt")
    cl = chomp(cl)
    clbytes = hex2bytes(cl)
    pttuple = genBestSingleByteXORDecrypt(clbytes)
    if pttuple[1] > bestscore
        bestscore = pttuple[1]
        bestdecrypt = pttuple[2]
        bestkey = pttuple[3]
    end
end;

In [ ]:
String(bestdecrypt)