Base64 编码原理简介和python的base64模块的使用

     Base64编码,首先我们应该搞清楚,为什么里面有个64的字样呢?其实是因为该编码使用64个明文来编码任意的二进制文件,它里面只使用了A-Z,a-z,0-9,+,/这64个字符,有“略懂”的同学就会说了,里面还有“=”号啊,不错,不过等号不属于编码字符,而是填充字符。

    还有就是,为什么发明这么个编码呢,其实这个编码的原理是很简单的,“破解”也很容易,电子邮件刚出来的时候,只传递英文字符,这没有问题,但是后来,中国人,日本人都要发email,这样问题就来了,因为这些字符有可能会被邮件服务器或者网关当成命令处理,故必须得有一种编码来对邮件进行加密,但是加密的目的是为了能够使得一些原始的服务器不出问题(新得牛叉服务器已经能处理这些乱七八糟得情况了,不过因为已经形成了一套规范,所以邮件还是得经过Base64编码才能传递),这样加密必须得简单(那搞个取反,异或加密吧,:-),还是没解决根本问题咯),加密简单,这样客户端程序加密解密也快,又要是明文Ascii编码,这样Base64就诞生了。当初设计人员主要是考虑了两个问题:

1、加密算法复杂程度和效率
2、如何处理传输

    Base64基本都能满足,如果因为发一封邮件把CPU占到100%或者把内存给用完了,那就完全没必要了,编码之后只要普通人一眼看不出内容就行了。

    下面谈谈Base64的编码原理,按照RFC2045的定义,The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.我之前在网上查Base64的资料时,发现了一个很好的网站,
base64编码在线转换器 :http://www.motobit.com/util/base64-decoder-encoder.asp,大家对Base64感兴趣的话,可以去看看。Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节(4*6=24),之后在6位的前面补两个0,形成8位一个字节的形式。6bit2进制能表示的最大数是2的6次方减一,刚好是64,这也是为什么是64个字符的原因,这样就需要一张映射表,表如下:

The Base64 Alphabet


      Value Encoding  Value Encoding  Value Encoding  Value Encoding
           0 A            17 R            34 i            51 z
           1 B            18 S            35 j            52 0
           2 C            19 T            36 k            53 1
           3 D            20 U            37 l            54 2
           4 E            21 V            38 m            55 3
           5 F            22 W            39 n            56 4
           6 G            23 X            40 o            57 5
           7 H            24 Y            41 p            58 6
           8 I            25 Z            42 q            59 7
           9 J            26 a            43 r            60 8
          10 K            27 b            44 s            61 9
          11 L            28 c            45 t            62 +
          12 M            29 d            46 u            63 /
          13 N            30 e            47 v
          14 O            31 f            48 w         (pad) =
          15 P            32 g            49 x
          16 Q            33 h            50 y

    编码原理:将3个字节转换成4个字节((3 X 8)=24=(4X6)),先读入3个字节,每读一个字节,左移8位,再右移四次,每次6位,这样就有4个字节了。
    解码原理:将4个字节转换成3个字节,先读入4个6位(用或运算),每次左移6位,再右移3次,每次8位,这样就还原了。

    Base64将3个字节转变为4个字节,因此,编码后的代码量(以字节为单位,下同)约比编码前的代码量多了1/3。如果代码量正好是3的整数倍,那么恰好多了1/3。但如果不是呢?这个时候“=”终于派上用场啦,当代码量不是3的整数倍时,代码量/3的余数自然就是2或者1。转换的时候,结果不够6位的用0来补上相应的位置,之后再在6位的前面补两个0。转换完空出的结果就用就用“=”来补位,总之要保证最后编码出来得字节数是4的倍数。

    原理也说了表也给,大家可以编码了哈……

    再说说python对Base64的支持,有个base64模块,专门干这个事情的,大家去看看就行了,直接贴点例子代码。

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# utility @ Python
# Functions: Base64 编解码模块
# Created By MagicTong on 2008-07-16

import base64
import os
import StringIO

# encode,decode, encodestring,decodestring, b64encode,b64decode, urlsafe_b64decode,urlsafe_b64encode
    
class KBase64:
    """
    Base64 编码和解码模块,用于对文件,字符串,URL的编解码
    对base64的简单封装
    """
    
    def __init__(self):
        pass
    
    def encodeFile(self, strFileName, strDecName):
        """
        将一个文件的内容编码为Base64
        """
        
        if not os.path.exists(strFileName):
            return False
        
        f1 = None
        f2 = None
        try:
            f1 = open(strFileName, "r")
            f2 = open(strDecName, "w")
        
            base64.encode(f1, f2)
            
        except Exception, e:
            print e
            if f1 != None:
                f1.close()
            if f1 != None:
                f2.close()
            return False
                
        f1.close()
        f2.close()
        return True
    
    def decodeFile(self, strFileName, strDecName):
        """
        将一个Base64文件的内容解码
        """
        
        if not os.path.exists(strFileName):
            return False
        
        f1 = None
        f2 = None
        try:
            f1 = open(strFileName, "r")
            f2 = open(strDecName, "w")
        
            base64.decode(f1, f2)
            
        except Exception, e:
            print e
            if f1 != None:
                f1.close()
            if f1 != None:
                f2.close()
            return False
                
        f1.close()
        f2.close()
        return True
    
    def encodeSting(self, strSrc):
        """
        对字符串进行Base64编码
        """
        try:
            strDec = base64.encodestring(strSrc)
        except Exception, e:
            print e
            return "", False
        
        return strDec, True
    
    def decodeSting(self, strSrc):
        """
        将Base64字符串解码为源字符串
        """
        try:
            strDec = base64.decodestring(strSrc)
        except Exception, e:
            print e
            return "", False
        
        return strDec, True
    
if __name__ == "__main__":
    baseObj = KBase64()
    print baseObj.encodeSting("a")

    python还有专门处理邮件的编解码的email模块,更方便啊,大家先看一份邮件的源文件:

Received: from dbmail.kingsoft.com (192.168.8.252) by mail.kingsoft.cn
 (192.168.13.1) with Microsoft SMTP Server id 8.1.240.5; Mon, 3 Mar 2008
 10:52:20 +0800
Received: from unknown (HELO linyehui) (linyehui@219.131.196.66)  by localhost
 with SMTP; 3 Mar 2008 03:08:58 -0000
From: =?gb2312?B?wdbStrvU?= <linyehui@kingsoft.com>
To: =?gb2312?B?VG9uZ0xlaSBbza/A2l0=?= <TongLei@kingsoft.com>,
 =?gb2312?B?THVIb25neWFuZyBbwr266dH0XQ==?= <LuHongyang@kingsoft.com>,
 =?gb2312?B?THVZaXdhbmcgW8Ks0ubN+l0=?= <LuYiwang@kingsoft.com>,
 =?gb2312?B?TGluWWVodWkgW8HW0ra71F0=?= <LinYehui@kingsoft.com>,
 =?gb2312?B?TGlKaWFuIFvA7r2jXQ==?= <LiJian@kingsoft.com>,
 =?gb2312?B?TGlEZWhvbmcgW8DutcK66l0=?= <LiDehong@kingsoft.com>,
 =?gb2312?B?SmlhbmdXYW5nc2hlbmcgW72qzfrJ+l0=?= <JiangWangsheng@kingsoft.com>,
 =?gb2312?B?R2VuZ1poYW9oZSBbuaLV17rYXQ==?= <GengZhaohe@kingsoft.com>,
 =?gb2312?B?RGVuZ1BlbmcgW7XLxfRd?= <DengPeng@kingsoft.com>,
 =?gb2312?B?Q2hlbmdIdWkgW7PMu9Rd?= <chenghui@kingsoft.com>,
 =?gb2312?B?Q2hlblpoaXFpYW5nIFuzwta+x79d?= <ChenZhiqiang@kingsoft.com>
Date: Mon, 3 Mar 2008 10:50:54 +0800
Subject: =?gb2312?B?W7vh0um8x8K8XTIwMDgwMzAz1ty1/LT6u+Ff0N7V/bDmsb4=?=
Thread-Topic: =?gb2312?B?W7vh0um8x8K8XTIwMDgwMzAz1ty1/LT6u+Ff0N7V/bDmsb4=?=
Thread-Index: Ach82ZpIBkzrq2yfQl2VA1yMdD4T2g==
Message-ID: <200803031050475158814@kingsoft.com>
Accept-Language: zh-CN, en-US
Content-Language: zh-CN
X-MS-Exchange-Organization-AuthAs: Anonymous
X-MS-Exchange-Organization-AuthSource: mail.kingsoft.cn
X-MS-Has-Attach:
X-MS-Exchange-Organization-SenderIdResult: PermError
X-MS-Exchange-Organization-SCL: 1
X-MS-Exchange-Organization-PCL: 2
X-MS-Exchange-Organization-PRD: kingsoft.com
X-MS-TNEF-Correlator:
x-scanvirus: By EQAVSE AntiVirus Engine
x-scanresult: CLEAN
x-mailfrom: <linyehui@kingsoft.com>
x-rcptto: <tonglei@kingsoft.com>
x-fromip: 219.131.196.66
x-eqmanager-scaned: 1
x-eqauthuser: linyehui
x-received: unknown,219.131.196.66,20080303110858
received-spf: PermError (mail.kingsoft.cn: domain of linyehui@kingsoft.com
 used an invalid SPF mechanism)
Content-Type: text/plain; charset="gb2312"
Content-Transfer-Encoding: base64
MIME-Version: 1.0

yc/W3Lmk1/fX3L3ho7oNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLQ0KwdbStrvUDQqjsaGi1ti5ubXEzsi2qLmk1/cNCqOyoaLD3LGjobDR3tXV
w8WhsbCyyKu1urzTx7+5psTcsOaxvs/gudgNCqOzoaLHqNLGtPrC6w0Ko7Shote8sbi907Cy17DG
97W9sLLIq9bQ0MSjqMq1z9ZQcm94eaOpDQqzwta+x78NCqOxoaK/tLT6wusNCqOyoaLI7bz+1f3U
2tTL0NDEo7/pDQqjs6GisLLXsNTL0NC1yMSjv+m1xLLiytQNCqO0oaK199PDza/A2rXExKO/6cqx
o6zO9rm5yrGz9rTtDQqjtaGivMa7rqO6yrXP1qGhtffTw21zabXEyO28/tC21NgNCsDuvaMNCqOx
oaLKtc/WzfjVvsjP1qTR3cq+o8KjyKPPDQqjsqGita+/8s7KzOKjqLLpyv2+3cyrvsPBy7vhta+j
qQ0Ko7OhokhhbzEyM6Gi5dvTzsr9vt0oyKW19NbYuLTT0DHN8jEpDQqjtKGiTWFjZru5yqOjtM3y
tuDK/b7dw7uy6bW9o6zDu7Lptb21xNe8sbi808nP19S2r8nPsai5psTcDQrNr8DaDQqjsaGiRVhF
16qzybf+zvENCqOyoaLN6snG0K3S6crVyKFFWEUNCqOzoaLX1Mb0tq+zzNDyy9HL9w0Ko7ShorzG
u66jurDRtKu13bXEdmVjdG9ysvC31rPJw7vT0LD817C5/bXEyv2+3dTZtKu13aGjDQrA7r78DQqj
saGisNm2yLCyyKvW0NDEt6KyvA0Ko7Khornj1t2z9rLuDQqjs6GivMa7rqO6vdNpbmZvYyiy6dGv
oaLJz7GoKQ0Ko7ShorzGu66jurCyyKvW0NDEvObI3XZpc3RhDQqzzLvUDQqjsaGidHVvdHXPwtTY
xKO/6b3TyOsNCqOyoaLI7bz+udzA7bj3u/mxvrmmxNzN6rPJDQqjs6GisuLK1L27uPizwta+x78N
CqO0oaK/qrv6xvS2r727uPjNr8DaDQqjtaGisb7W3Lmk1/e7+bG+zeqzyaOsu7nT0Ly4uPZCVUcN
Cg0KDQoNCrG+1ty8xruuo7oNCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tLS0tLS0tLS0tLS0tLQ0Ko7GhokxZSCCwssir1tDQxNPrsLLXsMb31q685LXEtPrA7aGiyOe5
+9Kqus3N+NPOus/X97XEu7C7udKqsNHW2Lm5sOaxvrXE19S2r9eisuG3/s7xtci808nPDQqjsqGi
x7bN+NKztcRFWEUNCqOzoaLN+NKzo6iworbFo6kNCqO0oaLX9tDFz6LOxLz+tcS5pL7fDQoNCg0K
MjAwOC0wMy0wMw0KwdbStrvUDQo=

    很乱是吧,不知所云,hoho,但是解码很简单,解码代码如下:

# coding=utf-8

import email

fp = open("magicTong.eml", "r")
msg = email.message_from_file(fp) # 直接文件创建message对象,这个时候也会做初步的解码
subject = msg.get("subject") # 取信件头里的subject, 也就是主题

# 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC?=这样的subject
h = email.Header.Header(subject)
dh = email.Header.decode_header(h)
subject = dh[0][0]
print "subject:", subject
print "from: ", email.utils.parseaddr(msg.get("from"))[1] # 取from
print "to: ", email.utils.parseaddr(msg.get("to"))[1] # 取to
print "Date: ", email.utils.parsedate(msg.get("Date"))

# 循环信件中的每一个mime的数据块
for par in msg.walk():
    if not par.is_multipart(): # 这里要判断是否是multipart,是的话,里面的数据是无用的,至于为什么可以了解mime相关知识。
        name = par.get_param("name") #如果是附件,这里就会取出附件的文件名
        if name:
            #有附件
            # 下面的三行代码只是为了解码象=?gbk?Q?=CF=E0=C6=AC.rar?=这样的文件名
            h = email.Header.Header(name)
            dh = email.Header.decode_header(h)
            fname = dh[0][0]
            print '附件名:', fname
            data = par.get_payload(decode=True) # 解码出附件数据,然后存储到文件中
            
            try:
                f = open(fname, 'wb') #注意一定要用wb来打开文件,因为附件一般都是二进制文件
            except:
                print '附件名有非法字符,自动换一个'
                f = open('aaaa', 'wb')
            f.write(data)
            f.close()
        else:
            #不是附件,是文本内容
            print par.get_payload(decode=True) # 解码出文本内容,直接输出来就可以了。
        
        print '+'*60 # 用来区别各个部分的输出
        
fp.close()
<这段代码不知道是哪个老兄的啦,我很久之前从网上拷贝下来的,能用就行啦>

    假设上面那个email的名字是magicTong.eml。解码内容如下:

subject: [会议记录]20080303周迭代会_修正版本
from:  linyehui@kingsoft.com
to:  TongLei@kingsoft.com
Date:  (2008, 3, 3, 10, 50, 54, 0, 1, -1)
上周工作总结:

------------------------------------------------------

林叶辉

1、重构的稳定工作

2、密保“艳照门”安全岛加强功能版本相关

3、迁移代码

4、准备接安装器到安全中心(实现Proxy)

陈志强

1、看代码

2、软件正在运行模块

3、安装运行等模块的测试

4、调用童磊的模块时,析构时出错

5、计划:实现 调用msi的软件卸载

李剑

1、实现网站认证演示BHO

2、弹框问题(查数据太久了会弹)

3、Hao123、遨游数据(去掉重复有1万1)

4、Macf还剩4万多数据没查到,没查到的准备加上自动上报功能

童磊

1、EXE转成服务

2、完善协议收取EXE

3、自启动程序搜索

4、计划:把传递的vector拆分成没有包装过的数据再传递。

李军

1、百度安全中心发布

2、广州出差

3、计划:接infoc(查询、上报)

4、计划:安全中心兼容vista

程辉

1、tuotu下载模块接入

2、软件管理各基本功能完成

3、测试交给陈志强

4、开机启动交给童磊

5、本周工作基本完成,还有几个BUG

 

 

 

本周计划:

------------------------------------------------------

1、LYH 安全中心与安装器之间的代理、如果要和网游合作的话还要把重构版本的自动注册服务等加上

2、嵌网页的EXE

3、网页(阿杜)

4、做信息文件的工具

 

 

2008-03-03

林叶辉


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

 

    o(∩_∩)o...哈哈,很方便吧


 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值