Python实现一些简单编码及加解密的转换
入门CTF一段时间,在处理一些简单密码题时,习惯于使用各类在线解密网站解题,但发现其中良萎不齐,经常给解题带来不必要的麻烦,于是尝试着自己用Python实现一些简单密码或字符数字的转换。(主要是想练习一下python的使用。。。)
1.各进制之间的转换
直接使用python的内置函数就行了
二进制(binary)前缀:0b或0B
八进制(octonary)前缀:0o或0O
十六进制(hexadecimal)前缀:0x或0X
- 任意进制转10进制
int(num)
或
int("num",sys)
# num为待转数字,sys为其进制
int(0X12ab) #16进制转10进制
>>> 4779
int("12ab",12) #12进制转10进制
>>>2147
-基础进制(2,8,10,16)转2进制 (无法任意进制)
bin(num)
>>> bin(8)
'0b1000'
>>> bin(8)[2:]
'1000'
- 转8进制
oct(num)
- 转16进制
hex(num)
- 10进制转任意进制(使用辗转相除法)
def Decconvert(dec,sys):
result = []
while (dec/sys)!=0:
a=dec%sys
if a>=10:
a=chr(65+(a-10))
result.append(a)
dec=int(dec/sys)
result.reverse()
for i in result:
print(i,end="")
print("")
Decconvert(22,12)
>>>1A #成功将10进制的22 转换为12进制的1A
2. string与bytes间的转换
python3中,字符串是unicode格式,字节包括utf-8,gbk等等,网络传输,硬盘保存是以字节格式保存的。
str和bytes格式的区别:
str:
表现形式:a=‘hello,world’
内部原理:
00000000 00000000 00000000 01101000 ‘h’
。。。
。。。
bytes:
表现形式:a=b’hello,world’
内部原理:
01101000 utf-8
。。。
。。。
00000000 01101000 gbk
。。。
。。。
以下为转换代码
b = b'' # 创建一个空的bytes
b = byte() # 创建一个空的bytes
b = b'hello' # 直接指定这个hello是bytes类型
b = bytes('string',encoding='编码类型') #利用内置bytes方法,将字符串转换为指定编码的bytes
b = str.encode('编码类型') #利用字符串的encode方法编码成bytes,默认为utf-8类型
str = b.decode('编码类型') #将bytes对象解码成字符串,默认使用utf-8进行解码。
3. 字符串与Base间的相互转化
以下代码以python3为例
# 字符串->base
import base64
string='字符串在这a' #输入字符串
string=string.encode('utf-8') #将其类型改为byte类型,因为b64encode函数的参数为byte类型
print("Base64:",str(base64.b64encode(string),'utf-8')) #结果转为字符类型输出
print("Base32:",str(base64.b32encode(string),'utf-8'))
print("Base16:",str(base64.b16encode(string),'utf-8'))
>>>
Base64: 5a2X56ym5Liy5Zyo6L+ZYQ==
Base32: 4WWZPZ5MU3SLRMXFTSUORP4ZME======
Base16: E5AD97E7ACA6E4B8B2E59CA8E8BF9961
base->字符串
import base64
print(str(base64.b64decode('5a2X56ym5Liy5Zyo6L+ZYQ=='),'utf-8'))
print(str(base64.b32decode('4WWZPZ5MU3SLRMXFTSUORP4ZME======'),'utf-8'))
print(str(base64.b16decode('E5AD97E7ACA6E4B8B2E59CA8E8BF9961'),'utf-8'))
>>>
字符串在这a
字符串在这a
字符串在这a
4. URL编码
“中文”和“特殊字符”使用UTF-8字符集来对应url编码,如”中”使用UTF-8字符集得到的字节为0xE4 0xB8 0xAD,经过Url编码之后得到”%E4%B8%AD”。
from urllib import parse
str1 = 'url编码'
str2 = parse.quote(str1) #将字符串进行编码
print(str2) #str2=url%E7%BC%96%E7%A0%81
str3 = parse.unquote(str2) #解码字符串
print(str3) #str3=url编码
5. 凯撒密码解密
直接附上解密代码
def caesar_Crypto(msg):
lowercase = 'abcdefghijklmnopqrstuvwxyz'
uppercase = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
result = []
offset = 1
while offset<=26:
temp = []
for char in msg:
if char in lowercase:
temp.append(chr(97 + (ord(char) - 97 + offset) % 26))
elif char in uppercase:
temp.append(chr(65 + (ord(char) - 65 + offset) % 26))
else:
temp.append(char)
string = "".join(temp)
print (string)
result.append(string)
offset += 1
return result
caesar_Crypto('LZYGQ326N5QXM')
6. 栅栏密码解密
def railfence(msg):
l=len(msg)
a=[]
for i in range(2,l):
if l%i==0:
a.append(i)
if a==[]:
print("输入字符不规范")
for j in a:
result=[]
for k in range(j):
for p in range(k,l,j):
result.append(msg[p])
string="".join(result)
print("%d字一栏:"%j+string)
railfence('adqwertt') #括号内输入字符串
>>>2字一栏:aqetdwrt
4字一栏:aedrqtwt
7. 维吉尼亚密码
#加密
def VigenereEncrypto (input,key) :
ptLen = len(input)
keyLen = len(key)
quotient = int(ptLen/keyLen) #商
remainder = ptLen % keyLen #余
out = ""
for i in range (0 , quotient) :
for j in range (0 , keyLen) :
c = int((ord(input[i*keyLen+j]) - ord('a') + ord(key[j]) - ord('a')) % 26 + ord('a'))
out += chr(c)
for i in range (0 , remainder) :
c = int((ord(input[quotient*keyLen+i]) - ord('a') + ord(key[i]) - ord('a')) % 26 + ord('a'))
out += chr(c)
print(out)
VigenereEncrypto('input','key')
>>>加密结果为:srnex
#解密
def VigenereDecrypto (output , key) :
ptLen = len (output)
keyLen = len (key)
quotient = int(ptLen/keyLen)
remainder = ptLen % keyLen
inp = ""
for i in range (0 , quotient) :
for j in range (0 , keyLen) :
c = int((ord(output[i*keyLen+j]) - ord('a') + 26 - (ord(key[j]) - ord('a'))) % 26 + ord('a'))
inp += chr (c)
for i in range (0 , remainder) :
c = int((ord(output[quotient*keyLen + i]) - ord('a') + 26 - (ord(key[i]) - ord('a'))) % 26 + ord('a'))
inp += chr (c)
print(inp)
VigenereDecrypto('srnex','key')
>>>input