# 【样章】Crypto 笔记 - 导引章 & 异或密码 1

## 关于

crypto- Modern Latin Greek kryptos “hidden”, from kryptein “to hide”

## Set 1 说明

beat oneself up v. 自责

## 1-1

Always operate on raw bytes, never on encoded strings. Only use hex and base64 for pretty-printing.

``````function getint(arr::BitArray, itr, type::Type{T} where T <: Integer = UInt8)
num = zero(type)
for i in itr
num <<= 1
if arr[i]
num += one(type)
end
end
num
end
function setint!(arr::BitArray, itr, num::Integer)
for i in reverse(itr)
arr[i] = Bool(num&0x1)
num >>= 1
end
end
``````

``````function hex2bitarr(hexstr)
arr = BitArray(undef, sizeof(hexstr)*4)
@inbounds for i in 1:sizeof(hexstr)
u8_ch = UInt8(hexstr[i])
n = u8_ch <= 0x39 ?
u8_ch - 0x30 :
u8_ch - 0x61 + 0xa
setint!(arr, i*4-3:i*4, n)
end
arr
end
``````

`Base64`

``````function base64unitencode(u8)
u8 <= 25 ? 'A' + u8 :
u8 <= 51 ? 'a' + u8 - 26 :
u8 <= 61 ? '0' + u8 - 52 :
u8 == 62 ? '+' : '/'
end
function bitarr2base64(arr)
n, r = divrem(length(arr), 6)
str = ""
@inbounds for i in 1:n
u8_64 = getint(arr, i*6-5:i*6, UInt8)
str *= base64unitencode(u8_64)
end
if !iszero(r)
u8_64 = getint(arr, n*6+1:length(arr), UInt8) <<
(6-r)
str *=  base64unitencode(u8_64)
end
m4 = sizeof(str) % 4
iszero(m4) || (str *= '='^(4-m4))
str
end
``````

``````function main()
readline(stdin) |> hex2bitarr |> bitarr2base64 |> println
end
``````

## 1-2

``````function main()
res = xor.(x, y) |> bitarr2hex |> println
end
``````

## 1-3

decrypt v.解密 devise v.设计

You can do this by hand. But don’t: write code to do it for you.

Character frequency is a good metric.

`1b 37 37 33 31 36 3f 78 15 1b 7f 2b 78 34 31 33 3d 78 39 78 28 37 2d 36 3c 78 37 3e 78 3a 39 3b 37 36`

`1b 37 37 33 31 36 3f` `15 1b 7f 2b` `34 31 33 3d` `39` `28 37 2d 36 3c` `37 3e` `3a 39 3b 37 36`

• `01100001` xor `?` = `00111001`
• `00100000` xor `?` = `01111000`

`?` = `01011000`，两个都符合。

`Cooking MC's like a pound of bacon`

`1-4` 中告诉我们这里代码还得写。

``````const word_freq = [
0.0651738, 0.0124248, 0.0217339, 0.0349835, 0.1041442,
0.0197881, 0.0158610, 0.0492888, 0.0558094, 0.0009033,
0.0050529, 0.0331490, 0.0202124, 0.0564513, 0.0596302,
0.0137645, 0.0008606, 0.0497563, 0.0515760, 0.0729357,
0.0225134, 0.0082903, 0.0171272, 0.0013692, 0.0145984,
0.0007836
]
const space_freq = 0.1918182
``````

``````function score_en_text(str)
score = zero(Float64)
for c in str
if c == 0x20
score += space_freq
elseif 0x61 <= c <= 0x7a
@inbounds score += word_freq[c - 0x61]
elseif 0x41 <= c <= 0x5a
@inbounds score += word_freq[c - 0x41]
end
end
score
end
``````

``````function main()
len = length(arr)>>3
@inbounds str = [getint(arr, i*8-7:i*8, UInt8)::UInt8 for i in 1:len]
vec = Tuple{Float64, UInt8}[]
sizehint!(vec, 128)
for key in 0x0:0x7f
score = xor.(str, key) |> score_en_text
push!(vec, (score, key))
end
sort!(vec, by = first, rev = true)
#= @inbounds for i in 1:10
score, key = vec[i]
for j in 1:len
xor(str[j], key) |> Char |> print
end
println(" [\$(score), \$(key)]")
end =#
@inbounds key = vec[1][2]
@inbounds for i in 1:len
xor(str[i], key) |> Char |> print
end
end
``````

## 1-4

``````using Downloads
function l1_4_get()
url = "https://cryptopals.com/static/challenge-data/4.txt"
buf = IOBuffer()
str = String(take!(buf))
split(str, '
'; keepempty = false)
end
function l1_3_try(str)
vec = Tuple{Float64, UInt8}[]
sizehint!(vec, 127)
for key in 0x1:0x7f
score = xor.(str, key) |> score_en_text
push!(vec, (score, key))
end
sort!(vec, by = first, rev = true)
return vec[1]
end
function main()
nhex = l1_4_get()
len = length(nhex)
vec = Tuple{Float64, Int}[]
sizehint!(vec, len)
hscore = -Inf64
realkey = 0
reali = 0
for (i, hex) in enumerate(nhex)
if sizeof(hex) != 60
continue
end
@inbounds text = [
hexunitencode(hex[i*2-1]) << 4 |
hexunitencode(hex[i*2]) for i in 1:30]
score, key = l1_3_try(text)
if score > hscore
hscore = score
realkey = key
reali = i
end
end
hex = nhex[reali]
@info "Result" hscore realkey hex
text = [hexunitencode(hex[i*2-1]) << 4 |
hexunitencode(hex[i*2]) for i in 1:30]
@inbounds for c in text
xor(c, realkey) |> Char |> print
end
end
``````

• 里面混了个长度 58 的
• 意思并不是除一个以外其它都是正常文本的十六进制表示

``````┌ Info: Result
│   hscore = 1.7887731999999998
│   realkey = 0x35
└   hex = "7b5a4215415d544115415d5015455447414c155c46155f4058455c5b523f"
Now that the party is jumping
``````
1 个赞