python中涉及到的编码和解码

  • 缘起:在网上拉取互联网(公司内图片数据库(http访问))上图片数据并在线训练时,需要将通过requests 打开并read得到的网页数据进行解码,因为读取到的网页对象(图片对象)为字节流,需要将字节流类型转为uint8类型numpy数组,再进一步解码为opencv中特定的(如cv2.IMREAD_COLOR)MAT对象,才能被opencv进行处理。具体代码:
            respone = requests.get(img_url,headers=headers)
            if 200 != respone.status_code:
                print("url is invalid %s " % img_url)
                continue
            cont = respone.content
            image = np.asarray(bytearray(cont), dtype="uint8")
            image = cv2.imdecode(image, cv2.IMREAD_COLOR)
            

其中使用到了python。bytearray类型转换,其目的是将其强转为bytearray类型。涉及到了bytearray类型及python中编解码相关知识,这里对其做一个梳理。

  • 注:本文引用了该博文:https://www.cnblogs.com/f-ck-need-u/p/10185965.html

GPT的回答:

1、基础概念

编码概念(除base64编码外):编码方案决定了我们如何将字符映射到计算机可以理解和存储的二进制数据。这当中,ASCII、UTF-8、和其他字符编码方法都涉及到如何将字符(或者更准确地说,字符串)转换为二进制数据。这个过程通常被称为"编码"。
我们可以从一个文本文件开始,文件中有一些文字,我们假设字符是 “Hello, World!”.

  1. ASCII编码:在早期的计算机系统中,ASCII(美国信息交换标准代码)被广泛用于表示字符。每个ASCII字符使用一个字节(8位)来表示,其中7位用来表示128种可能的字符,包括大、小写英文字母、数字0-9、以及一些特殊字符,剩余的1位通常用作校验位。在这个例子中,“Hello, World!” 中的每个字符都可以映射到一个特定的ASCII码。
  2. UTF-8编码:随着时间的推移,由于需要表示越来越多的特殊字符,比如各种语言的字母,表情符号等等,单纯的ASCII编码已经不能满足需求了。UTF-8就是Unicode字符集的一种实现方式,它用1到4个字节来表示每个字符,可以表示非常多的字符。对于ASCII字符,UTF-8编码与ASCII编码相同,也就是说,"Hello, World!"这个字符串在UTF-8编码下和ASCII编码下是一样的。
  3. 二进制数据:所有存储在计算机中的数据,无论使用哪种编码,最终都是以二进制形式存在的。"二进制"指的只有两个可能的数值:0和1。一个二进制的数字被称为位(bit),8个位组成一个字节(byte)。例如,"Hello, World!"在UTF-8编码下的二进制形式可能看起来是这样(只取前三个字符):
    H: 01001000
    e: 01100101
    l: 01101100
    
  4. Base64编码:有些系统只能处理文本数据,不能处理二进制数据。例如,在发送电子邮件时,邮件服务器只能处理ASCII字符。这时候,如果我们有一段二进制数据要发送,例如一张图片,我们就需要把这段二进制数据转换成文本数据,这就是Base64编码的作用。Base64编码会把每3个字节的二进制数据转换成4个ASCII字符。当接收者收到这些字符后,他们可以再转换回原来的二进制数据。
  5. 对于字符串:字符串是我们编程中经常操作的一种数据类型,它由一系列字符组成。在不同的语境下(例如不同的编程语言或者应用领域),“字符"这个词可以有不同的含义,但是在大多数情况下,一个字符可以被认为是一个字母、数字或者其他符号。
    编码方案决定了我们如何将字符映射到计算机可以理解和存储的二进制数据。这当中,ASCII、UTF-8、和其他字符编码方法都涉及到如何将字符(或者更准确地说,字符串)转换为二进制数据。这个过程通常被称为"编码”。
    例如,考虑字符串 ‘A’,在ASCII编码或UTF-8编码下,它会被映射到二进制序列 01000001(十进制中的65)。但是在其他字符编码(如UTF-16)中,同一个字符可能被编码成完全不同的二进制序列。
    Base64编码则稍微有些不同,它通常用于将非文本二进制数据(如图片或音频文件)转换为字符串,以便在只能处理文本数据的环境中(例如电子邮件)进行传输。在这个过程中,原始的二进制数据会被切割成6位长的小块,然后每一块都被映射到一个特定的字符(Base64字符集包括A-Z, a-z, 0-9, +, /和=)。
    另外值得一提的是,在许多编程语言中,包括Python和JavaScript等,字符串数据类型的内部已经自动处理了字符编码和解码的问题,开发者通常只需要关心如何操作这些字符串,而不需要去管理底层的编码细节。

2.进阶一点

  1. 二进制字符串(在 Python 中是 bytes 类型) 与真正字符串(str)的区别与联系。
    在Python中,bytesstr(字符串)都用于存储文本/字符数据,但是它们之间存在一些重要的区别:
  • 二进制字符串(bytes)bytes 类型在 Python 中被用来表示二进制数据。这种数据类型包含一系列的字节,每个字节都是 0 到 255 (或者 00 到 FF,采用十六进制)之间的整数。bytes 对象只能包含 ASCII 字符,或者说它是一个 ASCII 字符组成的数组,因此它适合用来处理二进制数据,如图像、文件、网络传输等。** 通俗解释就是: ASCII 字符组成的串**。
  • 文字字符串(str)str 类型则用来处理 Unicode 字符串,也就是我们通常意义上所说的字符串。str 对象可以包含任何 Unicode 字符。对于纯英文文本,str 的行为与 bytes 非常相似,这是因为 Unicode 字符集的前 128 个字符与 ASCII 字符一一对应
    他们两者之间的主要联系在于它们都可以用来处理和存储字符串或者字符数据,但是各有其特定使用场景。当你需要处理文本数据(特别是包含非 ASCII 字符的)时,一般使用 str;当你需要处理二进制数据时,则使用 bytes
    在两者之间进行转换也很常见,例如你在问题中提到的代码段:
video_encode = base64.b64encode(video_content)  # 此处 video_encode 是 bytes
video_encode = video_encode.decode('utf-8')  # 此处 video_encode 是 str

在第一行,我们得到的是一个 bytes 对象。然后我们调用 .decode('utf-8') 方法将其转换为 str 对象。这个过程实际上是一种编码转换:从 Bytes 转换为 UTF-8 编码的字符串。

  • 更深入地探究上面两行代码:
    • 在Base64编码原理,我们将二进制数据每3个字节为一组,编码为4个ASCII字符。这是因为3个字节有24个比特,而4个Base64字符(每个字符可以表示64种状态,即6个比特)刚好也有24个比特。而base64.b64encode()函数返回的是字节字符串(即由二进制字节构成的字符串),其本质上还是二进制数据。
    • 那么既然输出的还是二进制串,那这个函数转换做了啥呢。具体地,现将原有二进制数据按照base64编码方式编码为对应的字符(3个字节可得到4个Base64字符),而这些字符对应的ASCII码字符的二进制表示就是这个函数结果中所指的字节数据(即这些字符还是用二进制存储的);基于原始二进制数据编码出多个base64字符的话就会得到字节串。
    • 由于base64.b64encode()函数返回的是字节串(本质还是二进制),就需要解码为utf-8类型的普通字符串以便进行传输
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值