python 密码学编程
最近在看一本书。名字是 python密码学编程。在此做一些笔记,同时也为有需要的人提供一些参考。
********************************************************************
* quote : "http://inventwithpython.com/" *
* python-version : 2.7.11 *
********************************************************************
1.第一种加密方法。反转加密法。
即通过反向输出消息来进行加密。例如将“Hello World” 加密成 “dlroW olleH”
这是一种非常弱的加密方式。么什了说它清弄以可然仍你,密加被已息信条这使即
message = "Three can keep a secret,if two of them are dead."
translated = '' i = len(message) - 1
while i >= 0:
translated = translated + message[i]
i = i - 1
print translated
实现思路也非常简单。就是把一个String从后到前拼接到另一个String上。
至于解密。可以使message 为加密后的密文,打印出来的即为明文。
2.凯撒加密法
凯撒加密(Caesar cipher)是一种简单的消息编码方式:它根据字母表将消息中的每个字母移动常量位k。举个例子如果k等于3,则在编码后的消息中,每个字母都会向前移动3位:a会被替换为d;b会被替换成e;依此类推。字母表末尾将回卷到字母表开头。于是,w会被替换为z,x会被替换为a
message = "this is my secret message"
key = 13 mode = "encrypt"
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
translated = ''
message = message.upper() for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
if mode == "encrypt":
num = num + key
elif mode == "decrypt":
num = num - key if num >= len(LETTERS):
num = num - len(LETTERS)
elif num < 0:
num = num + len(LETTERS) translated = translated + LETTERS[num] else:
translated = translated + symbol print translated
首先。message 保存了要加密的消息。key 保存了秘钥。mode 表示模式,encrypt为加密,decrypt为解密。translated 为加密后的字符串。.upper()方法用来忽略大小写。
具体实现。遍历message 中的每一个字符。
如果该字符属于26个英文字母。
当模式为加密时,就把这个字符在字母表中的位置加上秘钥 key。用新的位置的字符来替换。如果加上秘钥之后的值超过了字母表的长度,我们需要回滚,即减去一个字母表的长度来确定它的新位置。
当模式为解密时,就减去key。注意位置小于0时要加上一个字母表的长度。
字符不是英文字母时不用替换,直接拼接到新字符串上即可。
3.暴力破解凯撒加密法
对于我们上面那种情况的凯撒加密法,我们可以发现可能的秘钥最多只有26个。于是我们可以尝试暴力破解,即尝试每一个可能的秘钥。
message = "GUVF VF ZL FRPERG ZRFFNTR"
LETTERS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' for key in range(len(LETTERS)):
translated = ''
for symbol in message:
if symbol in LETTERS:
num = LETTERS.find(symbol)
num = num - key
if num < 0:
num += len(LETTERS)
translated += LETTERS[num]
else:
translated += symbol
print "Key %s : %s"%(key , translated)
这段代码和上面的代码有很多相似。
message 存储了密文。其余代码对应了上面的 decrypt 模式。
我们打印出了26中可能的解密。
4.换位加密法
换位加密法不是替换字符,而是搞乱消息符号的顺序。
例如消息 Common sense is not so common.
假设使用数字 8 作为秘钥。也就是我们将在每一行放最多8个字符。(包含空格和标点)
对于上面这条消息,我们可以画出这样一个方格图
| C | o | m | m | o | n | s | |
| e | n | s | e | i | s | ||
| n | o | t | s | o | c | ||
| o | m | m | o | n | . |
最后一行的两个格子涂黑忽略它们。
正常的阅读方式应该是横向去读。如果我们把消息用列向表示出来,它的混乱程度足以让别人看不清原来的消息
密文是 Cenoonommstmme oo snnio. s s c (表中的空格需要表示,黑色方格直接忽略)
def main():
myMessage = "Common sense is not so common."
myKey = 8 ciphertext = encryptMessage(myKey , myMessage) print ciphertext + "|" def encryptMessage(key , message):
ciphertext = ['']*key for col in range(key):
pointer = col while pointer < len(message):
ciphertext[col] += message[pointer]
pointer += key
return ''.join(ciphertext) if __name__ == "__main__":
main()
具体到 encryptMessage 函数。我们首先创建了一个 list ,其中包含了 8(key)个空元素。这对应了上面表格中的8 (key) 列。
我们遍历这 8 列。
在第一列,我们依次拼接 原 message 中的 第 0,8,16,24......个字符。直到超出了 message 的长度。
在第二列,我们依次拼接 原 message 中的 第 1,9,17,25......个字符。直到超出了 message 的长度。
以此类推。
.join 方法将 list 转换为字符串然后 return。
换位加密法的解密过程:
当我们收到密文和秘钥之后。我们需要画一个表格。表格行数等于秘钥,列数等于 密文长度除以秘钥然后向上取整。
例如 密文 “Cenoonommstmme oo snnio. s s c”长度30,秘钥key = 8,我们需要画8行4列的表格
从左上角开始向右填。那么从上往下阅读时我们会看到明文(其实这两个表格的关系就类似于矩阵的倒置)
| C | e | n | o |
| o | n | o | m |
| m | s | t | m |
| m | e | o | |
| o | s | n | |
| n | i | o | . |
| s | |||
| s | c |
import math def main():
myMessage = "Cenoonommstmme oo snnio. s s c"
myKey = 8 ciphertext = decryptMessage(myKey , myMessage) print ciphertext + "|" def decryptMessage(key , message):
numOfColumns = int(math.ceil(len(message) / float(key)))
numOfRows = key
numOfShadeBoxes = (numOfColumns * numOfRows) - len(message)
plaintext = [''] * numOfColumns col = 0
row = 0
for symbol in message:
plaintext[col] += symbol
col += 1 if col == numOfColumns or col == numOfColumns - 1 and row >= numOfRows - numOfShadeBoxes:
col = 0
row += 1
return ''.join(plaintext) if __name__ == "__main__":
main()
这个程序完全按照和前面填表格的方式进行。
先从第0行开始,依次填第零列,第一列,第二列,第三列
然后跳到下一行,依次进行
其中。numOfShadedboxes 表示的是黑方格数,也就是默认不填字符的位置。程序会跳过这些地方填字符。
好的。现在让我们来写一个测试程序证明前面的加密和解密程序在对应不同的 message 和 key 时确实能正常工作。
import random,sys,transpositionEncrypt,transpositionDecrypt def main():
random.seed(42)
for i in xrange(20):
message = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" * random.randint(4,40)
message = list(message)
random.shuffle(message)
message = ''.join(message)
print "Test #%s : %s..."%(i+1,message[:50]) for key in xrange(1,len(message)):
if message != transpositionDecrypt.decryptMessage(key , transpositionEncrypt.encryptMessage(key, message)):
print "Mismatch with key %s and message %s"%(key , message)
sys.exit()
print "Transposition cipher test passed." if __name__ == "__main__":
main()
其中。import 语句中。transpositionEncrypt , transpositionDecrypt 为我们之前写的换位法 加密 和 解密 的py程序名。
测试中,我们生成了一个全英文字母的随机字符串并打乱了顺序,通过测试在将一个字符串加密再解密后是否能得到原来的字符串来判断程序是否正常工作。
python 密码学编程的更多相关文章
- 【python密码学编程】5.反转加密法
#Reverse Cipher message = 'there can keep a secret,if two of them are dead.' translated = '' i = len ...
- python 密码学编程 -- 2
接上一篇随笔 ******************************************************************** * quote : "http://i ...
- 【python密码学编程】8.使用换位加密法加密
替代加密法:用其他字符替代原有字符 换位加密法:搞乱字符顺序 [换位加密法]需要一个密钥 仅允许非商业转载,转载请注明出处
- 【python密码学编程】7.暴力破解凯撒加密法
# _*_ coding:utf-8 _*_ #Caeser Ciper import pyperclip messgae = 'GUVF VF ZL FRPERG ZRFFTNR.' nums = ...
- 【python密码学编程】6.凯撒加密法
凯撒加密法的迷药是0~25的整数 # _*_ coding:utf-8 _*_ #Caeser Ciper import pyperclip messgae = 'this is my secret ...
- 《Python游戏编程快速上手》|百度网盘免费下载|Python基础编程
<Python游戏编程快速上手>|百度网盘免费下载| 提取码:luy6 Python是一种高级程序设计语言,因其简洁.易读及可扩展性日渐成为程序设计领域备受推崇的语言. 本书通过编写一个个 ...
- Python Socket 编程——聊天室示例程序
上一篇 我们学习了简单的 Python TCP Socket 编程,通过分别写服务端和客户端的代码了解基本的 Python Socket 编程模型.本文再通过一个例子来加强一下对 Socket 编程的 ...
- python多线程编程
Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...
- python 面向对象编程学习
1. 问题:将所有代码放入一个py文件:无法维护 方案:如果将代码才分放到多个py文件,好处: 1. 同一个名字的变量互相不影响 2.易于维护 3.引用模块: import module 2.包:解决 ...
随机推荐
- ES6的开发环境搭建
在搭建es6开发环境之前,先简单介绍一下es6. ECMAScript 6.0(以下简称 ES6)是 JavaScript 语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得 Java ...
- php根据经纬度获取城市名
/*php根据经纬度获取城市名*/ function get_my_addr_infos(){ $ch = curl_init(); $timeout = 5; $lat = $list['info' ...
- Struts2拦截器记录系统操作日志
前言 最近开发了一个项目,由于项目在整个开发过程中处于赶时间状态(每个项目都差不多如此)所以项目在收尾阶段发现缺少记录系统日志功能,以前系统都是直接写在每个模块的代码中,然后存入表单,在页面可以查看部 ...
- Java IO学习笔记(四)打印流
1.只有输出流才有打印流:PrintWriter和PrintStream分别针对字符和字节,提供了重载的print,Println方法用于多种数据类型的输出.PrintWriter和PrintStre ...
- 基于Spring MVC 实现拦截器
Spring MVC 拦截器 一,具体内容: 在所有的开发之中拦截器属于一个重要的组件,可以说几乎所有的项目都会提供的概念应用,不管是Spring MVC,还是Struts 2.x都是提供有拦截器的, ...
- 优化js脚本设计,防止浏览器假死
在Web开发的时候经常会遇到浏览器不响应事件进入假死状态,甚至弹出"脚本运行时间过长"的提示框,如果出现这种情况说明你的脚本已经失控了,必须进行优化. 为什么会出现这种情况呢,我们 ...
- Jsp页面用table表格来让文字和文本框对齐
1, border="0" cellpadding="0" cellspacing="20", 第一个是页边距要设置0,第二个是用来指定单元 ...
- [问题解决]linux sudo xxx:command not found
题外话 软件的安装在linux下主要分为两种.一种是通过包管理器例如ubuntu的apt-get xxx,另一种是自己手动安装.通过包管理器安装的,基本开箱即用,无需配置,但是存在一个问题,有时候无法 ...
- oh-my-zsh配置
oh-my-zsh是做什么的 开源的zsh配置工具,它的主题和插件系统可以为zsh扩展外观和很多有用的功能,官方是这样介绍的: Oh-My-Zsh is an open source, communi ...
- python基础(5):数字和字符串类型
今天总结一下数据类型中的数字和字符串型. 预习: 小练习 一.数字(int,float) 在python3中数字类型只有整形,浮点型,复数.而复数在平时的编程中几乎用不到所以我们只要掌握整形和浮点型即 ...