簡體   English   中英

了解在上下文中編碼和解碼以將字符串保存在磁盤上的需要

[英]Understanding the need of encoding and decoding in context to saving the strings on disk

我已經在這里閱讀了答案。 我了解字節流是什么(1 和 0 的流),編碼是(從該流到我們人類理解的字符的映射)和解碼是(從字符到相應字節的反向映射)。

我仍然無法在腦海中協調整個概念。 在 RAM 中,我們已經將所有內容都作為字節。 而且我猜我的解釋器本質上是使用某種解碼方案來向我顯示與該字節流相對應的字符。 那么在保存到磁盤之前必須編碼是什么意思? 如果我的解釋器使用 'utf-8' 向我們顯示我正在輸入的文本,並且我要求它使用 'cp-1252' 保存該文本,我是否更改了底層字節流?

有不同的方式可以看到它。

在路上:“世界你好!” 可以用不同的方式編碼。 您需要字符串的語義:因此是稱呼和目標。 但是如果您保存到 UTF-8 文件,您將擁有不同的值,如在 UTF-16LE 文件中或在 EBCDIC 編碼中。

例如, A在 ASCII 編碼中為 65,但在 EBCDIC 編碼中為 193(例如被許多 IBM 大型機使用),在 UTF-16 編碼中為 0 65(或 65 0)。 等等。所以當你保存一個數字時,你需要指定編碼(正如讀者所期望的那樣,所以它可能取決於文件格式)。

但一種語言的庫也無法處理所有編碼(對於所有函數)。 通常最好使用標准庫進行解碼,然后在數據應該輸出時進行編碼。 所以你只需要實現編碼和解碼(例如對於 EBCDIC),而不是所有的排序、大寫/小寫處理、is_digits、is_symbol 等。

將語義與實際值分開是標准做法。 或者用邏輯顯示。 如果您是控制狂,則無需解碼值即可完成所有操作。 但是它很容易出錯,你應該知道很多細節,很少有人想知道。

另一個例子,你需要知道你的數據/字符串的真實值嗎? 你有一個數字,它是小端編碼還是大端編碼? 或者作為一個浮點數(例如 JavaScript)。 我們只知道,當我們保存數據時(例如在互聯網上發送,我們需要一種方法來告訴排序。或者在保存圖像時:我們告訴排序,所以在某些機器上,當讀取大數據時,字節會被交換數字)。

或者另一個例子:你自拍。 您有一個圖像,但您可以將其保存為 PNG 文件或 JPEG 文件:您將獲得具有不同值的非常不同的文件。 但是您知道編碼(幸運的是,對於此類圖像文件,第一個字節描述格式,然后很少有關於編碼的數據)。 對你來說,知道這是你的形象就足夠了。 但是你認為計算機會接受這兩種格式的字節嗎? 可能沒有。 當您讀取圖像時,您將在內存中轉換為不同的編碼(但您可能不需要關心它):通常是 RGB(或 RGBA)格式,但每個通道有多少位,或者是否有某種顏色渲染(來自配置文件),你不知道[JPEG 將其另存為 YCC]

Python 有更嚴格的語義觀點:您不知道 Python 將如何對字符串進行編碼。 它可能是 8 位:ASCII/Latin1,或 16 位 (UCS2),或 32 位 (UTF-32)。 它根據存儲字符串的最有效方式動態處理內部編碼。 您仍然可以獲得一個代碼點,每個字符的一個,以及許多字符串/字符函數。 就在那時你編碼一個字符串,你有一個固定的數字序列。 在字符串方面,您真的不知道字符串在內存中是如何表示的。 因此,這使 Unicode 的兩個不同部分明確分開:語義值(所有字符的描述)和編碼/解碼(如何以字節表示值)。

當您在 Python 中處理字符串時,您應該只關心語義。 實現(以及字符串在內存中的物理布局)不是你的業務,Python 可以改變它。 (它改變了它)。

但是用你的例子:

你可能不會得到太多,因為最近的標准化:ASCII 幾乎成為最常見的拉丁字母和符號的唯一編碼。 Latin-1 與 ASCII 兼容,只是從 7 位擴展到 8 位。 “Windows ANSI”使用Latin-1 並在未分配的部分添加字符。 基於拉丁語 1 的 Unicode(前 256 個字符)。 因此,您可能會看到具有固定編號(或不可用)的字符,但這不是規則,在早期的 Windows 中也是如此。

因此,您的cp-1252適用於大多數與 UTF-8 兼容的字符(但很少有字符)。 但是,如果您使用其他編碼,則應該進行大量轉碼(從一種編碼更改為另一種編碼)。 但通常你只在保存時這樣做:你保留內部編碼,但你做了一個副本來保存。

一個字節是 8 位,無論是在 RAM 中、磁盤上還是網絡上。

位是計算機數據的“原子”。 一個字節就是“分子”,只不過字節只有一種。

位是計算機中最小的信息單位。 通常說它代表 0 或 1,或 OFF 或 ON。

您是否將一個字節“解釋”為數字(0 到 255)、有符號數(-128 到 +127)、“ascii”字符(如我正在輸入的字符)取決於您(或計算機)做什么與字節。 或者一個字節可以是一個更大的數字的一部分,一個需要幾個字節來表示的數字。

因為有太多的“字母”或“字符”(尤其是中文),要裝在一個字節中,就有了一個“字符”可能由多個字節組成的附加概念。 UTF-8 是當今的主要標准。 Giacomo 討論了幾種不太常見的編碼,這些編碼說明了一個字節(或多個字節)表示什么“字符”。 請記住,每個字節由 8 位組成。

英文字母和數字以及一些標點符號以與 Ascii、Latin1、cp-1252 和 UTF-8(以及一些其他編碼)相同的方式以字節表示(編碼)。 但是一旦你進入歐洲重音字母,編碼就會發生分歧。

您可能聽說過的一種常見做法是將一個字節表示為兩個十六進制數字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM