- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
假设我在 Python 中有一个字符串:
>>> s = 'python'
>>> len(s)
6
现在我像这样编码
这个字符串:
>>> b = s.encode('utf-8')
>>> b16 = s.encode('utf-16')
>>> b32 = s.encode('utf-32')
我从上面的操作中得到的是一个字节数组——也就是说,b
、b16
和 b32
只是字节数组(当然,每个字节都是 8 位长)。
但我们对字符串进行了编码。那么这是什么意思?我们如何将“编码”的概念附加到原始字节数组?
答案在于这些字节数组中的每一个都是以特定方式生成的。让我们看看这些数组:
>>> [hex(x) for x in b]
['0x70', '0x79', '0x74', '0x68', '0x6f', '0x6e']
>>> len(b)
6
这个数组表示对于每个字符我们有一个字节(因为所有字符都在 127 以下)。因此,我们可以说将字符串“编码”为“utf-8”会收集每个字符对应的代码点并将其放入数组中。如果代码点不能放在一个字节中,那么 utf-8 会占用两个字节。因此 utf-8 消耗尽可能少的字节数。
>>> [hex(x) for x in b16]
['0xff', '0xfe', '0x70', '0x0', '0x79', '0x0', '0x74', '0x0', '0x68', '0x0', '0x6f', '0x0', '0x6e', '0x0']
>>> len(b16)
14 # (2 + 6*2)
在这里我们可以看到,“编码为 utf-16”首先将两个字节的 BOM (FF FE
) 放入字节数组中,然后,对于每个字符,它将两个字节放入大批。 (在我们的例子中,第二个字节总是零)
>>> [hex(x) for x in b32]
['0xff', '0xfe', '0x0', '0x0', '0x70', '0x0', '0x0', '0x0', '0x79', '0x0', '0x0', '0x0', '0x74', '0x0', '0x0', '0x0', '0x68', '0x0', '0x0', '0x0', '0x6f', '0x0', '0x0', '0x0', '0x6e', '0x0', '0x0', '0x0']
>>> len(b32)
28 # (2+ 6*4 + 2)
在“utf-32 编码”的情况下,我们首先放入 BOM,然后为每个字符放入四个字节,最后将两个零字节放入数组中。
因此,我们可以说“编码过程”为字符串中的每个字符收集 1、2 或 4 个字节(取决于编码名称),并在它们前面添加和追加更多字节以创建最终的字节结果数组。
现在,我的问题:
b
、b16
和b32
的内存表示实际上是一个字节列表。字符串的内存表示是什么?字符串在内存中究竟存储了什么?encode()
时,每个字符对应的代码点被收集(代码点对应于编码名称)并放入一个数组或字节中。当我们执行 decode()
时到底发生了什么?最佳答案
首先,UTF-32是一个4字节的编码,所以它的BOM也是一个四字节的序列:
>>> import codecs
>>> codecs.BOM_UTF32
b'\xff\xfe\x00\x00'
并且由于不同的计算机体系结构以不同方式处理字节顺序(称为 Endianess ),因此 BOM 有两种变体,小端和大端:
>>> codecs.BOM_UTF32_LE
b'\xff\xfe\x00\x00'
>>> codecs.BOM_UTF32_BE
b'\x00\x00\xfe\xff'
BOM 的目的是将该订单传达给解码器;阅读 BOM,您知道它是大端还是小端。因此,UTF-32 字符串中的最后两个空字节是最后编码字符的一部分。
UTF-16因此,BOM 很相似,因为有两种变体:
>>> codecs.BOM_UTF16
b'\xff\xfe'
>>> codecs.BOM_UTF16_LE
b'\xff\xfe'
>>> codecs.BOM_UTF16_BE
b'\xfe\xff'
默认使用哪一个取决于您的计算机架构。
UTF-8根本不需要 BOM; UTF-8 每个字符使用 1 个或多个字节(根据需要添加字节以编码更复杂的值),但这些字节的顺序在标准中定义。 Microsoft 认为无论如何有必要引入 UTF-8 BOM(因此其记事本应用程序可以检测 UTF-8),但由于 BOM 的顺序从不改变,因此不鼓励使用它。
至于unicode字符串,Python存储的是什么;实际上在 Python 3.3 中发生了变化。在 3.3 之前,在 C 级别内部,Python 存储 UTF16 或 UTF32 字节组合,这取决于 Python 是否使用宽字符支持编译(参见 How to find out if Python is compiled with UCS-2 or UCS-4?,UCS-2 本质上 UTF- 16 和 UCS-4 是 UTF-32)。因此,每个字符占用 2 或 4 个字节的内存。
从 Python 3.3 开始,内部表示使用表示字符串中所有字符所需的最小 字节数。对于纯 ASCII 和 Latin1 可编码文本,使用 1 个字节,用于 BMP 的其余部分使用 2 个字节,并使用包含超过 4 个字节的字符的文本。 Python 根据需要在格式之间切换。因此,在大多数情况下,存储变得更加高效。有关详细信息,请参阅 What's New in Python 3.3 .
我可以强烈建议您阅读 Unicode 和 Python:
关于 python 3 : Demystifying encode and decode methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13469591/
我得到了一些有趣的结果,试图辨别使用 Encode::decode("utf8", $var) 之间的区别。和 utf8::decode($var) .我已经发现,在一个变量上多次调用前者最终会导致错
我尝试使用 FlushedInputStream :Android decoder->decode returned false for Bitmap download 但没有任何变化,因为我使用:B
我有一小部分代码: from pyasn1.type import univ from pyasn1.codec.ber import decoder decoder.decode(binary_fi
这个问题在这里已经有了答案: Instantiated optional variable shows as nil in Xcode debugger (2 个答案) 关闭 2 年前。 在 Swi
我在 Playground 中有以下示例代码。如果结果符合 Decodable 协议(protocol),我想解码网络请求的结果。 知道为什么这段代码不起作用吗? protocol APIReques
我正在尝试使用 imagecreatefromwebp() 将 webp 文件转换为 JPEG,但不幸的是,它向我发出警告:警告:imagecreatefromwebp():WebP 解码:无法解码输
我试图覆盖 JSONDecoder 解码数据的方式。 我尝试了以下方法: struct Response : Decodable { init(from decoder: Decoder) t
ACTIVATE_THIS = """ eJx1UsGOnDAMvecrIlYriDRlKvU20h5aaY+teuilGo1QALO4CwlKAjP8fe1QGGalRoLEefbzs+Mk Sb7
我正在尝试使用 swift 4 来解析本地 json 文件: { "success": true, "lastId": null, "hasMore": false,
我的代码有问题。 我正在尝试使用ExtJS和Codeigniter制作上传文件格式。 这是我的下面的代码, Ext.require([ 'Ext.form.field.File',
我有一些遗留代码正在调用 sun.net.www.ParseUtil.decode()。我想避免调用供应商特定的函数,所以我想用其他东西替换调用。 我可以使用 java.net.URLDecoder.
使用 Sonatype Nexus,我仅在访问 /nexus/#admin/support/status 时收到此错误消息. Ext.JSON.decode(): You're trying to d
我正在学习 Elm,让我感到困惑的一件事是“Json.Decode.succeed”。根据docs succeed : a -> Decoder a Ignore the JSON and produ
有什么区别 URLDecoder.decode(String s) 和 URLDecoder.decode(String s, String enc) 我有一个 cookie 值,例如 val=%22
使用 Google Apps 脚本,我想解码 HTML,例如: Some text & text ¢ 存储为: Some text & text ¢ 所以,类似的问题:How t
我正在对带有字幕的视频进行编码,但出现错误“解码的字幕文本中的 UTF-8 无效;可能缺少 -sub_charenc 选项。解码流时出错”,但视频还是编码了。忽略此错误的后果是什么?谷歌搜索显示一个人
我有如下代码: cn_bytes = [157, 188, 156] cn_str = "" clen = len(cn_bytes) count = int(clen / 3) for x in r
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 4年前关闭。 Improve thi
This script give you a decoded listing from an encoded file. Supports *,je, ,vbe, .asp, .hta, .htm,
telnet客户端响应如何解码 我认为这是一个特定的响应,因为所有思科服务器都有相同的响应.这段文字的名称是什么,我如何解密它 '\xff\xfb\x01\xff\xfb\x03\xff\xfd\x1
我是一名优秀的程序员,十分优秀!