zoukankan      html  css  js  c++  java
  • python学习笔记---python3中Base64编码时参数不能为str

    base64

    原理

    base64就是对二进制数据进行编码,比如我有6字节的二进制数据,然后每3个字节分为一组,也就是一组有3*8 = 24bit(1个字节由8位二进制数组成) ,然后把这个 24bit 分为4组,也就是每一组有6个bit。其实说白了base64就是将二进制数据每6个bit分为一组,6个bit就是6位二进制的数,最大的是111111,对应十进制就是63,也就是6位二进制数能够表示 0~63个字符。

    比如 6位二进制数是111111 那么对应的就是 /  ,就会将 / 最终返回给我们 

    如果要编码的二进制数据不是3的倍数,最后会剩下1个或2个字节怎么办?此时,需在原数据后面添加1个或2个零值字节,使其字节数是3的倍数。然后,在编码后的字符串后面添加1个或2个等号“=”,表示所添加的零值字节数。解码的时候,会自动去掉。

    优点:可以将二进制数据转换成可打印字符,方便传输数据;对数据进行简单的加密,肉眼安全。

    缺点:内容编码后的体积会变大,编码和解码需要额外的工作量。

    它的使用场景有很多,比如将图片等资源文件以Base64编码形式直接放于代码中,使用的时候反Base64后转换成Image对象使用;有些文本协议不支持不可见字符的传递,只能转换成可见字符来传递信息。有时在一些特殊的场合,大多数消息是纯文本的,偶尔需要用这条纯文本通道传一张图片之类的情况发生的时候,就会用到Base64,比如多功能Internet 邮件扩充服务(MIME)就是用Base64对邮件的附件进行编码的。

    下面用法报错:


    # 错误示例
    import base64
    s = '我是字符串'
    a = base64.b64encode(s) # 3.0版本以上 不允许接收 str 为参数 必须为byte

    Traceback (most recent call last):
      File "<pyshell#70>", line 1, in <module>
      a = base64.b64encode(s)
      File "D:工作软件pythonlibase64.py", line 58, in b64encode
      encoded = binascii.b2a_base64(s, newline=False)
    TypeError: a bytes-like object is required, not 'str'

    正确用法:

    >>> import base64
    >>> s = '我是字符串'
     
    # 先进行编码 转换为字节
    >>> s = s.encode() # 默认是utf8
    >>> s     # byte类型数据以16进制来表示
    b'xe6x88x91xe6x98xafxe5xadx97xe7xacxa6xe4xb8xb2'
    >>> a = base64.b64encode(s) # 在编码时会自动将16进制转换为2进制,然后每6bit一组,再找到对应的字符
    >>> a
    b'5oiR5piv5a2X56ym5Liy'
    >>> base64.b64decode(b'5oiR5piv5a2X56ym5Liy').decode('utf8') 
    '我是字符串'
     
     
    # 转成其他编码也是可以的
    >>> s = s.encode('gbk')
    >>> s
    b'xcexd2xcaxc7xd7xd6xb7xfbxb4xae'
    >>> a = base64.b64encode(s)
    >>> a
    b'ztLKx9fWt/u0rg=='
    >>> base64.b64decode(b'ztLKx9fWt/u0rg==').decode('gbk')                         
    '我是字符串'

    由于标准的Base64编码后可能出现字符+/,在URL中就不能直接作为参数,所以又有一种"url safe"的base64编码,其实就是把字符+/分别变成-_

    >>> base64.b64encode(b'ixb7x1dxfbxefxff')
    b'abcd++//'
    >>> base64.urlsafe_b64encode(b'ixb7x1dxfbxefxff')
    b'abcd--__'
    >>> base64.urlsafe_b64decode('abcd--__')
    b'ixb7x1dxfbxefxff'

    还可以自己定义64个字符的排列顺序,这样就可以自定义Base64编码,不过,通常情况下完全没有必要。

    Base64是一种通过查表的编码方法,不能用于加密,即使使用自定义的编码表也不行。

    Base64适用于小段内容的编码,比如数字证书签名、Cookie的内容等。

    由于=字符也可能出现在Base64编码中,但=用在URL、Cookie里面会造成歧义,所以,很多Base64编码后会把=去掉:

    去掉=后怎么解码呢?因为Base64是把3个字节变为4个字节,所以,Base64编码的长度永远是4的倍数,因此,需要加上=把Base64字符串的长度变为4的倍数,就可以正常解码了。

    如下:

    import base64
     
    def base64encode(raw):
        return base64.urlsafe_b64encode(raw).strip("=")
     
    def base64decode(data):
        return base64.urlsafe_b64decode(data + "=" * (-len(data)%4))

    ————————————————
    版权声明:本文为CSDN博主「苝花向暖丨楠枝向寒」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_40247263/java/article/details/82423051

  • 相关阅读:
    servlet之中文乱码:request.getParameter()
    html页面标题增加图标方法
    前端页面设计素材网站
    修电脑大全,学会不求人
    十篇TED点击率最高演讲,带你重新认识大数据与人工智能
    除了乔布斯,科技圈还有哪些大佬值得充信仰?
    快速建设网站的框架
    前端框架资源汇总
    获取页面跳转携带参数问题
    值得关注的博客和网站
  • 原文地址:https://www.cnblogs.com/jackron/p/13197454.html
Copyright © 2011-2022 走看看