鱼C论坛

 找回密码
 立即注册
查看: 9952|回复: 35

[技术交流] python小练习(002):简单字符串加密解密(基础篇)

[复制链接]
发表于 2016-11-14 20:40:12 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 jerryxjr1220 于 2016-11-15 08:29 编辑

昨天的python小练习顺利完成。传送门

今天的题目是:简单的英文字符串加密解密(基础篇)

我们知道电脑上的每个字符都有一个唯一编码,通用的标准是 ASCII (American Standard Code for Information Interchange 美国信息交换标准编码)。例如大写A = 65, 星号(*) = 42,小写k = 107。

一种现代加密方法是用一个密钥中的给定值,与一个文本文件中字符的 ASCII 值进行异或。使用异或方法的好处是对密文使用同样的加密密钥可以得到加密前的内容。例如,65 XOR 42 = 107, 然后 107 XOR 42 = 65。

对于不可攻破的加密,密钥的长度与明文信息的长度是一样的,而且密钥是由随机的字节组成的。用户将加密信息和加密密钥保存在不同地方,只有在两部分都得到的情况下,信息才能被解密。

不幸的是,这种方法对于大部分用户来说是不实用的。所以一种修改后的方案是使用一个密码作为密钥。如果密码比信息短,那么就将其不断循环直到明文的长度。平衡点在于密码要足够长来保证安全性,但是又要足够短使用户能够记得。

我们的任务很简单:设计一个转换程序,可以把一个字符串(可以仅限于AscII码范围内,不考虑中文字符,或其他非utf-8编码)和任意密钥进行加密和解密操作。

例如:         输入明文:Father,密钥:god, 输出密文:33,14,16,15,10,22
                输入密文:33,14,16,15,10,22, 密钥:god, 输出明文:Father

评分

参与人数 1鱼币 +5 收起 理由
SixPy + 5 热爱鱼C^_^

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2016-11-14 22:14:13 | 显示全部楼层
本帖最后由 jerryxjr1220 于 2016-11-15 11:51 编辑

无标题.png

python2的解答:
  1. import sys
  2. reload(sys)
  3. sys.setdefaultencoding('gbk')

  4. def encodes(string, key):
  5.         keys = key*(len(string)//len(key))+key[:len(string)%len(key)]
  6.         output = []
  7.         for i,s in enumerate(string):
  8.                 output.append(str(ord(s)^ord(keys[i])))
  9.         return ','.join(output)
  10.        
  11. def decodes(string, key):
  12.         string = string.split(',')
  13.         keys = key*(len(string)//len(key))+key[:len(string)%len(key)]
  14.         output = []
  15.         for i,s in enumerate(string):
  16.                 output.append(chr(int(s)^ord(keys[i])))
  17.         return ''.join(output)

  18. en_string = raw_input(u'请输入要加密的文字:')
  19. en_key = raw_input(u'请输入要加密的密钥:')
  20. output = encodes(en_string, en_key)
  21. print u"密文为: "+output
  22. raw_input()
  23. de_string = raw_input(u'请输入要解密的文字(以","分隔):')
  24. de_key = raw_input(u'请输入要解密的密钥:')
  25. output = decodes(de_string, de_key)
  26. print u"明文为: "+output
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 1

使用道具 举报

发表于 2016-11-14 22:41:22 | 显示全部楼层
还是有点小遗憾没有看到之前的题目
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-14 22:46:32 | 显示全部楼层
  1. def deal(tips,key):
  2.     ltips=len(tips)
  3.     lkey=len(key)
  4.     secret=[]
  5.     num=0
  6.     for each in tips:
  7.         if num>=lkey:
  8.             num=num%lkey
  9.         secret.append(ord(each)^ord(key[num]))
  10.         num+=1
  11.     return secret

  12. tips=input('输入明文:')
  13. key=input('密钥:')
  14. secret=deal(tips,key)
  15. print('输出密文:%s'%secret)

  16. ##解密

  17. def deal2(tips,key):
  18.     ltips=len(tips)
  19.     lkey=len(key)
  20.     secret=[]
  21.     num=0
  22.     for each in tips:
  23.         if num>=lkey:
  24.             num=num%lkey
  25.         tempt=int(each)
  26.         secret.append(tempt^ord(key[num]))
  27.         num+=1
  28.     return secret


  29. s=input('输入密文:')
  30. tips=s.split()
  31. key=input('密钥:')
  32. secret=deal2(tips,key)
  33. print('输出明文:',end=' ')
  34. for each in secret:
  35.     print(chr(each),end='')



复制代码

对于输入内容的格式要求较苛刻(密文输入格式必须为,空格间隔),欢迎大家完善
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-14 23:26:25 | 显示全部楼层
我的思路:以密钥为随机数的种子,将字符依次与随机数异或。
  1. import random
  2. choice = input('加密(1)还是解密(2)?')
  3. def encode(str1, key):
  4.     random.seed(key)
  5.     str2 = ''
  6.     for c in str1:
  7.         str2 += str(ord(c) ^ random.randint(0, 255)) + ','
  8.     str2 = str2.strip(',')
  9.     return str2

  10. def decode(str2, key):
  11.     random.seed(key)
  12.     str1 = ''
  13.     for i in str2.split(','):
  14.         i = int(i)
  15.         str1 += chr(i ^ random.randint(0, 255))
  16.     return(str1)
  17.    
  18. if choice == '1':
  19.     str1 = input('请输入明文:')
  20.     key = input('请输入密钥:')
  21.     str2 = encode(str1, key)
  22.     print(str2)
  23. elif choice == '2':
  24.     str2 = input('请输入密文,数字间用英文逗号分隔:')
  25.     key = input('请输入密钥:')
  26.     str1 = decode(str2, key)
  27.     print(str1)
  28. else:
  29.     print('输入错误!')
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-11-15 09:01:49 | 显示全部楼层
python 2里面要输入输出中文真是蛋疼啊。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2016-11-15 11:56:37 | 显示全部楼层
冬雪雪冬 发表于 2016-11-14 23:26
我的思路:以密钥为随机数的种子,将字符依次与随机数异或。

这个方法也不错,可以不用考虑密钥和密文的长度问题。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-15 13:20:11 | 显示全部楼层
本帖最后由 SixPy 于 2016-11-15 13:47 编辑

XOR  crypt
  1. from itertools import islice, cycle

  2. def fn_XOR(txt,key):
  3.     key=bytes(key,'ascii')
  4.     return (a^b for a,b in zip(islice(cycle(key),len(txt)),txt))

  5. def crypt(txt,key):
  6.     return ','.join(map(str, fn_XOR(bytes(txt,'ascii'),key)))

  7. def decry(txt,key):
  8.     txt=bytes(map(int, txt.split(',')))
  9.     return bytes(fn_XOR(txt,key)).decode()

  10. if __name__ == '__main__':
  11.     while 1:
  12.         flg = int(input('加密 0\n解密 1\n>'))
  13.         if flg in (0,1): break
  14.         
  15.     txt = input('输入%s文内容:'% '明密'[flg])
  16.     key = input('输入密码:')
  17.     print('%s文:%s' % ('密明'[flg], decry(txt,key)if flg else crypt(txt,key)))
复制代码

  1. 加密 0
  2. 解密 1
  3. >0
  4. 输入明文内容:Father
  5. 输入密码:god
  6. 密文:33,14,16,15,10,22
  7. >>>


  8. 加密 0
  9. 解密 1
  10. >1
  11. 输入密文内容:33,14,16,15,10,22
  12. 输入密码:god
  13. 明文:Father
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-17 17:42:13 | 显示全部楼层
感觉那么随机数加密的很不错,收下自己做了一个程序给密码加密
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-22 23:12:30 | 显示全部楼层
新手表示还看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 1 反对 0

使用道具 举报

发表于 2016-11-25 11:01:05 | 显示全部楼层
本帖最后由 776667 于 2016-11-25 11:07 编辑
  1. import os

  2. def encode(plaintext,key):
  3.     key = key*(len(plaintext)//len(key)) + key[:len(plaintext)%len(key)]
  4.     ciphertext = []
  5.     for i in range(len(plaintext)):
  6.         ciphertext.append(str(ord(plaintext[i])^ord(key[i])))
  7.     return ','.join(ciphertext)

  8. def decode(ciphertext,key):
  9.     ciphertext = ciphertext.split(',')
  10.     key = key*(len(ciphertext)//len(key)) + key[:len(ciphertext)%len(key)]
  11.     plaintext = []
  12.     for i in range(len(ciphertext)):
  13.         plaintext.append(chr(int(ciphertext[i])^ord(key[i])))
  14.     return ''.join(plaintext)

  15. if __name__ == '__main__':
  16.     function = input('输入E进入加密模式,输入D进入解密模式,输入其它按键关闭程序,请输入:')
  17.     if function == 'E':
  18.         plaintext = input('请输入要加密的文字:')
  19.         key = input('请输入要加密的密钥:')
  20.         print('密文为:%s'%encode(plaintext,key))
  21.         os.system('pause')
  22.     if function == 'D':
  23.         ciphertext = input('请输入要解密的文字(以\',\'分割):')
  24.         key = input('请输入要加密的密钥:')
  25.         print('明文为:%s'%decode(ciphertext,key))
  26.         os.system('pause')
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-30 13:20:32 | 显示全部楼层
冬雪雪冬 发表于 2016-11-14 23:26
我的思路:以密钥为随机数的种子,将字符依次与随机数异或。

问一下,random.seed(key), 这个的意思是加密和解码过程都是随机的吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-11-30 14:10:14 | 显示全部楼层
墨菲斯托 发表于 2016-11-30 13:20
问一下,random.seed(key), 这个的意思是加密和解码过程都是随机的吗?

所有计算机软件生成的随机数都是伪随机数,一般我们看到的每个序列都是不一致的,原因是加上了一个种子,这个种子多采用实时的时间值。
这里人为的给出一个固定的种子,生成的一组随机数就是确定的了。无论是加密还是解密,都用的同一组随机数。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-1 09:04:08 | 显示全部楼层
冬雪雪冬 发表于 2016-11-30 14:10
所有计算机软件生成的随机数都是伪随机数,一般我们看到的每个序列都是不一致的,原因是加上了一个种子, ...

哦,好的,明白了
谢谢了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-16 21:04:10 | 显示全部楼层
棒棒哒!!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-17 20:50:06 | 显示全部楼层
大神啊,感觉楼主厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2016-12-18 14:13:45 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

头像被屏蔽
发表于 2016-12-18 14:16:02 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-12-18 18:11:07 | 显示全部楼层
厉害
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2016-12-18 21:56:44 | 显示全部楼层
不错
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 23:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表