Base64编码是一种“防君子不防小人”的编码方式,广泛应用于URL编码传输、MIME协议等,作为电子邮件的传输编码,生成的编码可逆,后一两位可能有“=”,生成的编码都是ascii字符。

 

base64 特点

优点:速度快,ascii字符,肉眼不可理解

缺点:编码比较长,非常容易被破解,仅适用于加密非关键信息的场合

 

base64 示例

"i love mimvp.com" 的base64编码

1)PHP 实现

echo "i love mimvp.com  ->  " . base64_encode('i love mimvp.com');
i love mimvp.com   ->   aSBsb3ZlIG1pbXZwLmNvbQ==

 

2)Python 实现

>>> import base64
>>> base64.b64encode('i love mimvp.com')
'aSBsb3ZlIG1pbXZwLmNvbQ=='

 

Python中进行Base64编码和解码

>>> import base64
>>> s = '我是字符串'
>>> a = base64.b64encode(s)
>>> print a
ztLKx9fWt/u0rg==
>>> print base64.b64decode(a)
我是字符串

 

代码实例

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Copyright of mimvp.com

import base64

def test_base64():
    base64_m3u8 = 'ZDNmYmE1MWJiMTZlMTJiZmE3M2NkODljNWM4NGY4MjIubTN1OA=='
    base64_path = 'L3lvdWt1L2FuaW1lX2dlbnJlLzBlNjE1MmM0NDZkZTExZTRhYmRhL2RlZmF1bHQvWE9ERXdOemN4TkRNeS9IRA=='
    base64_vol = 'dm9sOA=='
    
    m3u8 = base64.b64decode(base64_m3u8)
    path = base64.b64decode(base64_path)
    vol = base64.b64decode(base64_vol)
    
    origin_str = "\r\n{m3u8}\r\n{path}\r\n{vol}".format(m3u8=m3u8, path=path, vol=vol)
    base64_str = "\r\n{m3u8}\r\n{path}\r\n{vol}".format(m3u8=base64.b64encode(m3u8), path=base64.b64encode(path), vol=base64.b64encode(vol))
    
    print('origin_str: ' + origin_str)
    print('base64_str: ' + base64_str)

运行结果:

origin_str: 
d3fba51bb16e12bfa73cd89c5c84f822.m3u8
/youku/anime_genre/0e6152c446de11e4abda/default/XODEwNzcxNDMy/HD
vol8

base64_str: 
ZDNmYmE1MWJiMTZlMTJiZmE3M2NkODljNWM4NGY4MjIubTN1OA==
L3lvdWt1L2FuaW1lX2dlbnJlLzBlNjE1MmM0NDZkZTExZTRhYmRhL2RlZmF1bHQvWE9ERXdOemN4TkRNeS9IRA==
dm9sOA==

 

base64 扩展功能

base64模块是用来作base64编码解码的,这种编码方式在电子邮件中是很常见的,它可以把不能作为文本显示的二进制数据编码为可显示的文本信息,编码后的文本大小会增大1/3。

这里主要介绍一下base64的8个方法(encode, decode, encodestring, decodestring, b64encode, b64decode, urlsafe_b64decode, urlsafe_b64encode):

    1、encode, decode:用来编码和 解码文件的,也可以对StringIO里的数据做编解码
    2、encodestring, decodestring:用来编码和解码字符串
    3、b64encode, b64decode:用来编码和解码字符串,并且有一个替换符号字符的功能

#将c盘下1.txt(base64编码的内容)解码后存在c盘下2.txt中
import base64
 
filea = open(r'c:\1.txt','r')   
lines = filea.readlines()
writefile=open(r'c:\2.txt','w')
for i in lines:   
        word = i.strip()
        b = base64.decodestring(word)
        print b
        writefile.write(b)
        writefile.write('\n')
writefile.close()
filea.close()

 

shell 使用base64命令编码

echo abc | base64                     # 编码
echo YWJjCg== | base64 -d       # 解码

 

Base64 编码应用

标准的Base64并不适合直接放在URL里传输

因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。

例如:base64_encode('i love mimvp.com')   ->  aSBsb3ZlIG1pbXZwLmNv+b/Q==

为解决此问题,可采用一种用于URL的改进Base64编码,它在末尾填充'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。

此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)

 

Base64 原理

Base64要求把每三个8Bit的字节转换为四个6Bit的字节(3*8 = 4*6 = 24),然后把6Bit再添两位高位0,组成四个8Bit的字节,也就是说,转换后的字符串理论上将要比原来的长1/3。

Base64编码可用于在HTTP环境下传递较长的标识信息。例如,在Java Persistence系统Hibernate中,就采用了Base64来将一个较长的唯一标识符(一般为128-bit的UUID)编码为一个字符串,用作HTTP表单和HTTP GET URL中的参数。在其他应用程序中,也常常需要把二进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采用Base64编码不仅比较简短,同时也具有不可读性,即所编码的数据不会被人用肉眼所直接看到。

然而,标准的Base64并不适合直接放在URL里传输,因为URL编码器会把标准Base64中的“/”和“+”字符变为形如“%XX”的形式,而这些“%”号在存入数据库时还需要再进行转换,因为ANSI SQL中已将“%”号用作通配符。

为解决此问题,可采用一种用于URL的改进Base64编码,它不仅在末尾去掉填充的'='号,并将标准Base64中的“+”和“/”分别改成了“-”和“_”,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统一了数据库、表单等处对象标识符的格式。

另有一种用于正则表达式的改进Base64变种,它将“+”和“/”改成了“!”和“-”,因为“+”,“*”以及前面在IRCu中用到的“[”和“]”在正则表达式中都可能具有特殊含义。

此外还有一些变种,它们将“+/”改为“_-”或“._”(用作编程语言中的标识符名称)或“.-”(用于XML中的Nmtoken)甚至“_:”(用于XML中的Name)。

其他应用

Mozilla Thunderbird和Evolution用Base64来保密电子邮件密码

Base64 也会经常用作一个简单的“加密”来保护某些数据,而真正的加密通常都比较繁琐。

垃圾讯息传播者用Base64来避过反垃圾邮件工具,因为那些工具通常都不会翻译Base64的讯息。

 

 

Python中的urlencode 与 urldecode

url地址传说中含有中文,或者参数有中文的时候,这个算是很正常了,但是把这样的url作为参数传递的时候(最常见的callback),需要把一些中文甚至'/'做一下编码转换。

1、urlencode

urllib库里面有个urlencode函数,可以把key-value这样的键值对转换成我们想要的格式,返回的是a=1&b=2这样的字符串,比如:

>>> from urllib import urlencode
>>> data = {
...     'a': 'test',
...     'name': '魔兽'
... }
>>> print urlencode(data)
a=test&name=%C4%A7%CA%DE

如果只想对一个字符串进行urlencode转换,怎么办?

urllib提供另外一个函数:quote()

>>> from urllib import quote
>>> quote('魔兽')
'%C4%A7%CA%DE'

 

2、urldecode

当urlencode之后的字符串传递过来之后,接受完毕就要解码了——urldecode。

urllib提供了 unquote() 函数,但没有urldecode()

>>> from urllib import unquote
>>> unquote('%C4%A7%CA%DE')
'\xc4\xa7\xca\xde'
>>> print unquote('%C4%A7%CA%DE')
魔兽

 

3、讨论

在做urldecode的时候,看unquote()这个函数的输出,是对应中文在gbk下的编码

在对比一下quote()的结果不难发现,所谓的urlencode就是把字符串转车gbk编码,然后把\x替换成%。

如果你的终端是utf8编码的,那么要把结果再转成utf8输出,否则就乱码。

可以根据实际情况,自定义或者重写urlencode()、urldecode()等函数。

 

 

参考推荐

php 加密算法md5, sha1

PHP 对称加密AES算法

PHP 更安全的加密机制 Bcrypt

Python 常用加密算法 base64, md5, sha1

AES、DES、RSA三种典型加密算法

AES 加密算法的详细介绍与实现

PHP 使用cookie实现记住登录状态

PHP Session与Cookie详解

公钥,私钥,数字签名的通俗理解