凯撒密码破解

凯撒密码解密

原理

加密

对明文中的字母(不区分大小写)做偏移量处理

解密

统计密文字母频率表, 对偏移量的每种可能性做卡方统计, 最小统计值对应偏移量为加密偏移量

实现

加密

let2int 字母转化为字母表位置

int2let 字母表位置转化为字母

shift 加密单个字母

encode 加密字符串

加密 = 字母 c 左偏移 x 个位置

encode = map shift
graph LR A(明文)-->C[[encode]]-->B(密文)

频率表

table 期望频率表

count 计数

percent 百分比

freqs 计算观察频率表

频率 = 字母 c 个数 / 字母总个数

freqs = count 'a'..'z' / n
graph LR A(String)-->C[[freqs]]-->B(频率表)

解密

rotate 偏移频率表

chisqr 计算卡方统计

crack 解密

卡方 = chisqr 偏移观察频率表 期望频率表

解密 = encode (-最小卡方偏移)

最小卡方 = minimum $ chisqr (rotate 0-25 table') table
crack = encode (-最小卡方偏移)
graph LR A(观察频率表) --> B[[rotate 0-25]] --> C(偏移观察频率表) --> D[[chisqr]] --> E(卡方)
graph LR A(密文) --> B[[encode 负最小卡方偏移]] --> C(明文)

验证

明文

Haskell is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation.Designed for teaching, research, and industrial applications, Haskell pioneered several programming language features such as type classes, which enable type-safe operator overloading, and monadic input/output (IO). It is named after logician Haskell Curry. Haskell's main implementation is the Glasgow Haskell Compiler (GHC).

密文

偏移量 6

ngyqkrr oy g mktkxgr-vaxvuyk, yzgzoigrre zevkj, vaxkre latizoutgr vxumxgssotm rgtmagmk cozn zevk otlkxktik gtj rgfe kbgragzout.jkyomtkj lux zkginotm, xkykgxin, gtj otjayzxogr gvvroigzouty, ngyqkrr voutkkxkj ykbkxgr vxumxgssotm rgtmagmk lkgzaxky yain gy zevk irgyyky, cnoin ktghrk zevk-yglk uvkxgzux ubkxrugjotm, gtj sutgjoi otvaz/uazvaz (ou). oz oy tgskj glzkx rumoiogt ngyqkrr iaxxe. ngyqkrr'y sgot osvrksktzgzout oy znk mrgymuc ngyqkrr iusvorkx (mni).

解密

haskell is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation.designed for teaching, research, and industrial applications, haskell pioneered several programming language features such as type classes, which enable type-safe operator overloading, and monadic input/output (io). it is named after logician haskell curry. haskell's main implementation is the glasgow haskell compiler (ghc).

代码

import Data.Char
import Distribution.Utils.Generic (isAsciiAlpha)

-- 加密
let2int :: Char -> Int
let2int c | isAsciiLower c = ord c - ord 'a'
          | isAsciiUpper c = ord c - ord 'A'

int2let :: Int -> Char
int2let x = chr (ord 'a' + x)

shift :: Int -> Char -> Char
shift n c | isAsciiAlpha c = int2let $ (let2int c + n) `mod` 26
          | otherwise = c

encode :: Int -> String -> String
encode n = map (shift n) 

-- 频率表
table :: [Float]
table = [8.1, 1.5, 2.8, 4.2, 12.7, 2.2, 2.0, 6.1, 7.0,
        0.2, 0.8, 4.0, 2.4, 6.7, 7.5, 1.9, 0.1, 6.0,
        6.3, 9.0, 2.8, 1.0, 2.4, 0.2, 2.0, 0.1]

count :: Eq a => a -> [a] -> Int
count x = length . filter (== x)

percent :: Int -> Int -> Float
percent n m = (fromIntegral n / fromIntegral m) * 100

freqs :: String -> [Float]
freqs xs = map (\x -> percent (count x xs) n) ['a'..'z']
        where 
            n = length $ filter isAsciiAlpha xs 

-- 解密
chisqr :: [Float] -> [Float] -> Float
chisqr os es = sum [(o-e)^2/e | (o,e) <- zip os es]

rotate :: Int -> [a] -> [a]
rotate n xs = drop n xs ++ take n xs

crack :: String -> (Int, String)
crack xs = (factor, encode (-factor) xs)
    where
        table' = freqs xs
        chitab = map (\n -> chisqr (rotate n table') table) [0..25]
        factor = head $ (\x xs -> [i | (i, x') <- zip [0..] xs, x == x']) (minimum chitab) chitab

参考: Programming in Haskell ch5.5

posted @ 2025-05-19 19:18  (.)$(.)  阅读(17)  评论(0)    收藏  举报