#凯撒密码:将每一个字母替换为字母表中下一位字母,比如a变成b。

english.letters <- c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',

'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',

'w', 'x', 'y', 'z')

caesar.cipher <- list()

inverse.caesar.cipher <- list()

#加密LIST和解密LIST

for (index in 1:length(english.letters))

{

caesar.cipher[[english.letters[index]]] <- english.letters[index %% 26 + 1]

inverse.caesar.cipher[[english.letters[index %% 26 + 1]]] <- english.letters[index]

}

print(caesar.cipher)

# 单字符串加密

apply.cipher.to.string <- function(string, cipher)

{

output <- ''

for (i in 1:nchar(string))

{

output <- paste(output, cipher[[substr(string, i, i)]], sep = '')

}

return(output)

}

#向量字符串加密

apply.cipher.to.text <- function(text, cipher)

{

output <- c()

for (string in text)

{

output <- c(output, apply.cipher.to.string(string, cipher))

}

return(output)

}

apply.cipher.to.text(c('sample', 'text'), caesar.cipher)

#贪心优化:只有当新解密规则得到的解密串的概率变高时,才接受新的解密规则

#思路:

#1.如果解密规则B解密出的解密串的概率大于解密规则A对应的解密串,那么我们用B代替A

#2.如果解密规则B解密出的解密串的概率小于解密规则A对应的解密串,我们仍然有可能用B代替A,不过并不是每次都替换。

#如果解密规则B对应的解密串的概率是p1,解密规则A对应的解密串的概率是p2,以p1/p2的概率从解密规则A替换到解密规则B(表示有一定的概率接受B,这使得不会陷入贪心优化陷阱中)

#随便产生一个加密规则

generate.random.cipher <- function()

{

cipher <- list()

inputs <- english.letters

outputs <- english.letters[sample(1:length(english.letters), length(english.letters))]

for (index in 1:length(english.letters))

{

cipher[[inputs[index]]] <- outputs[index]  }

return(cipher)

}

modify.cipher <- function(cipher, input, output)

{

new.cipher <- cipher

new.cipher[[input]] <- output

old.output <- cipher[[input]]

collateral.input <- names(which(sapply(names(cipher), function (key) {cipher[[key]]}) == output))

new.cipher[[collateral.input]] <- old.output

return(new.cipher)

}

#对加密算法作一些修改

propose.modified.cipher <- function(cipher)

{

input <- sample(names(cipher), 1)

output <- sample(english.letters, 1)

return(modify.cipher(cipher, input, output))

}

#加载词典

load(file.path('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\07-Optimization\\data\\lexical_database.Rdata'))

#看一下里面的数据

lexical.database[['a']]

lexical.database[['the']]

lexical.database[['he']]

lexical.database[['she']]

lexical.database[['data']]

#取概率的,词典里有就返回,词典里没有返回一个最小的浮点数

one.gram.probability <- function(one.gram, lexical.database = list())

{

lexical.probability <- lexical.database[[one.gram]]

if (is.null(lexical.probability) || is.na(lexical.probability))

{

return(.Machine$double.eps)

}

else

{

return(lexical.probability)

}

}

#给定一个字符串向量,计算概率,概率不用连乘,用求和

log.probability.of.text <- function(text, cipher, lexical.database = list())

{

log.probability <- 0.0

for (string in text)

{

decrypted.string <- apply.cipher.to.string(string, cipher)

log.probability <- log.probability +

log(one.gram.probability(decrypted.string, lexical.database))

}

return(log.probability)

}

#

metropolis.step <- function(text, cipher, lexical.database = list())

{

#对加密规则作一下修改

proposed.cipher <- propose.modified.cipher(cipher)

#计算原加密规则及修改过的加密规则的概率

lp1 <- log.probability.of.text(text, cipher, lexical.database)

lp2 <- log.probability.of.text(text, proposed.cipher, lexical.database)

#如果新的比较好,直接换掉

if (lp2 > lp1)

{

return(proposed.cipher)

}

else

{

#如果旧的比较好,

a <- exp(lp2 - lp1)

#x是均匀分布的0~1间随机数

x <- runif(1)

if (x < a)

{

return(proposed.cipher)

}

else

{

return(cipher)

}

}

}

# 5个字符串的向量

decrypted.text <- c('here', 'is', 'some', 'sample', 'text')

#用凯撒加密规则加一下密

encrypted.text <- apply.cipher.to.text(decrypted.text, caesar.cipher)

set.seed(1)

#生成随机加密规则

cipher <- generate.random.cipher()

results <- data.frame()

#50000次迭代

number.of.iterations <- 50000

for (iteration in 1:number.of.iterations)

{

#算一下加密结果的概率

log.probability <- log.probability.of.text(encrypted.text,cipher,lexical.database)

#得出解密结果

current.decrypted.text <- paste(apply.cipher.to.text(encrypted.text, cipher),collapse = ' ')

#得出判断结果,1为正确,0为不正确

correct.text <- as.numeric(current.decrypted.text == paste(decrypted.text,

collapse = ' '))

#形成数据框,包括迭代次数,概率及解密后的结果,以及正确率

results <- rbind(results,data.frame(Iteration = iteration, LogProbability = log.probability,CurrentDecryptedText = current.decrypted.text,CorrectText = correct.text))

cipher <- metropolis.step(encrypted.text, cipher, lexical.database)

}

Machine Learning for hackers读书笔记(七)优化:密码破译的更多相关文章

  1. Machine Learning for hackers读书笔记(六)正则化:文本回归

    data<-'F:\\learning\\ML_for_Hackers\\ML_for_Hackers-master\\06-Regularization\\data\\' ranks < ...

  2. Machine Learning for hackers读书笔记(三)分类:垃圾邮件过滤

    #定义函数,打开每一个文件,找到空行,将空行后的文本返回为一个字符串向量,该向量只有一个元素,就是空行之后的所有文本拼接之后的字符串 #很多邮件都包含了非ASCII字符,因此设为latin1就可以读取 ...

  3. Machine Learning for hackers读书笔记_一句很重要的话

    为了培养一个机器学习领域专家那样的直觉,最好的办法就是,对你遇到的每一个机器学习问题,把所有的算法试个遍,直到有一天,你凭直觉就知道某些算法行不通.

  4. Machine Learning for hackers读书笔记(十二)模型比较

    library('ggplot2')df <- read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\12-Model_C ...

  5. Machine Learning for hackers读书笔记(十)KNN:推荐系统

    #一,自己写KNN df<-read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\10-Recommendations\\ ...

  6. Machine Learning for hackers读书笔记(九)MDS:可视化地研究参议员相似性

    library('foreign') library('ggplot2') data.dir <- file.path('G:\\dataguru\\ML_for_Hackers\\ML_for ...

  7. Machine Learning for hackers读书笔记(八)PCA:构建股票市场指数

    library('ggplot2') prices <- read.csv('G:\\dataguru\\ML_for_Hackers\\ML_for_Hackers-master\\08-PC ...

  8. Machine Learning for hackers读书笔记(五)回归模型:预测网页访问量

    线性回归函数 model<-lm(Weight~Height,data=?) coef(model):得到回归直线的截距 predict(model):预测 residuals(model):残 ...

  9. Machine Learning for hackers读书笔记(四)排序:智能收件箱

    #数据集来源http://spamassassin.apache.org/publiccorpus/ #加载数据 library(tm)library(ggplot2)data.path<-'F ...

随机推荐

  1. poj 2187

    求凸包后枚举凸包上的点 #include <cstdio> #include <cstdlib> #include <cmath> #include <map ...

  2. ASP.NET输出PNG图片时出现GDI+一般性错误的解决方法

    偶原来的用ASP.NET生成验证码图片时用的是JPG格式,今天想把它改成PNG格式的,结果就出现GDI+一般性错误,查了N久资料,才发现解决的办法,对分享此解决办法的网友深表感谢 Response.C ...

  3. spring事务认识

    Spring配置异常回滚采用的是rollback-for=“BusinessException”.来源于java的检查性异常.非检查性异常的区别.使用spring难免要用到spring的事务管理,要用 ...

  4. 用ScriptEngine在java中和javascript交互的例子(JDK6新特性)

    package demo7; import java.util.Arrays; import java.util.List; import javax.script.Invocable; import ...

  5. Java日志记录的事儿

    一.java日志组件 1.common-logging common-logging是apache提供的一个通用的日志接口.用户可以自由选择第三方的日志组件作为具体实现,像log4j,或者jdk自带的 ...

  6. SQL四舍五入及两种舍入

    round() 遵循四舍五入把原值转化为指定小数位数,如:round(1.45,0) = 1;round(1.55,0)=2floor()向下取整 如:floor(1.45)= 1,floor(1.5 ...

  7. (转)android屏幕适配

    声明:eoe文章著作权属于作者,受法律保护,转载时请务必以超链接形式附带如下信息 原文作者: zhuangyujia 原文地址: http://my.eoe.cn/zhuangyujia/archiv ...

  8. excel设置下拉菜单,并且不同值会显示不同颜色

    工作中常常要用的excel,每次都会有新的需求,然后不会,然后百度,然后过段时间可能就又忘了,于是就想说,自己记录下来~~~因为自己用的都是2010,其实哪个版本都差不多,都是应该可以找到相应的按钮滴 ...

  9. 【poj1284-Primitive Roots】欧拉函数-奇素数的原根个数

    http://poj.org/problem?id=1284 题意:给定一个奇素数p,求p的原根个数. 原根: { (xi mod p) | 1 <= i <= p-1 } is equa ...

  10. MongoDB (一) MongoDB 介绍

    MongoDB 是一个跨平台的,面向文档的数据库,提供高性能,高可用性和可扩展性方便. MongoDB工作在收集和文件的概念. 数据库 数据库是一个物理容器集合.每个数据库都有自己的一套文件系统上的文 ...