成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

文件和字符編碼

_Zhao / 2879人閱讀

摘要:為了消除文件格式和字符編碼的疑惑,上網(wǎng)搜索并翻出以前收藏的文章,心結(jié)總算了卻。本文即是對文件和字符編碼的個人總結(jié)。雙字節(jié)多字節(jié)字符,編碼方式和字節(jié)序,才是困擾程序員的問題。使用兩個字節(jié)表示一個字符,平臺默認的字符編碼方案都是。

轉(zhuǎn)載請注明來源:https://tlanyan.me/ascii-bina...

近期對識別文件格式感到好奇,不幸和字符編碼搞混,不明其中原理導致心煩意亂。為了消除文件格式和字符編碼的疑惑,上網(wǎng)搜索并翻出以前收藏的文章,心結(jié)總算了卻。本文即是對文件和字符編碼的個人總結(jié)。

文本文件和二進制

剛開始的疑惑是:文本文件和二進制文件有什么區(qū)別?為什么一個能顯示內(nèi)容,另一個的內(nèi)容經(jīng)常無法(用文本編輯器)正常顯示?

馬里蘭大學的這篇培訓筆記,把兩者的區(qū)別講得清楚:文本文件是二進制文件的一種,底層存儲也是0和1;文本文件可讀性和移植性好,但表現(xiàn)字符有限;二進制文件數(shù)據(jù)存儲緊湊,無字符編碼限制。文本文件基本上只能存放數(shù)字、文字、標點等有限字符組成的內(nèi)容;二進制沒有字符約束,可隨意存儲圖像、音視頻等數(shù)據(jù)。

用存儲數(shù)字的例子可以形象的看出文本文件和二進制文件存儲內(nèi)容上的差異。例如要存儲數(shù)字1234567890,文本文件要存儲0-9這十個數(shù)字的ASCII碼,對應的十六進制表示為:31 32 33 34 35 36 37 38 39 30,占用10個字節(jié);1234567890對應的二進制為“?0100 1001 1001 0110 0000 0010 1101 0010?”,占用4個字節(jié)(二進制表示32位,一個字節(jié)8位),存儲到文件的16進制表示為(大端):49 96 02 D2

文本文件按字符存放內(nèi)容,二進制按字節(jié)存放,這是兩種文件最本質(zhì)的區(qū)別。根據(jù)這個特性,可以推斷出一些常見結(jié)論:二進制文件常常比文本文件緊湊,占用空間少;文本文件更友好易用,能用所見即所得的方式編輯;二進制文件常常需要專用程序打開,等等。

回過頭看文本編輯器打開二進制文件常常是亂碼的現(xiàn)象。例如一個二進制文件存放了一個整數(shù)1234(四個字節(jié)),用16進制表示為:00 00 04 D2。文本編輯器打開后逐個字符解釋,會發(fā)現(xiàn)這幾個字節(jié)拼不出可顯示的字符,只好亂碼相待。亂碼的原因是文本編輯器不能正確解析字節(jié)流,這也是二進制文件需要用專用軟件打開的原因。例如jpg文件要用看圖軟件打開,如果用音樂播放器打開,完蛋!視頻文件要用播放器打開,用壓縮軟件打開,歇菜!

文件格式

了解文本文件和二進制文件的區(qū)別后,再來看文件格式。我們知道,Windows按文件拓展名識別文件格式,并調(diào)用對應的程序打開文件;(類)Unix系統(tǒng),拓展名可有可無,那么怎么知道這個文件是什么格式呢?

幸好有file命令,這個命令可以告訴我們文件到底是什么格式。文件拓展名不是文件格式的本質(zhì)區(qū)別,內(nèi)容才是。把a.zip改成a.txt/a.jgp/a.mp3,無論什么文件名,file都讓其原形畢露:Zip archive data, at least v1.0 to extract。

file命令的工作原理可這篇文章。

編碼

說完了文件,再來說文件內(nèi)容中的編碼。常見的127個ASCII字符,沒啥編碼好說的,反正幾乎所有的編碼方式都兼容它。雙字節(jié)、多字節(jié)字符,編碼方式和字節(jié)序,才是困擾程序員的問題。一個漢字,GBK編碼需要兩個字節(jié),還要考慮本機的大小端,才能確定存放的最終形式;網(wǎng)絡通訊時,要轉(zhuǎn)換成網(wǎng)絡字節(jié)序(大端序),接收方才能正常解析。開發(fā)人員如果對字符編碼不熟悉,通信時遇到亂碼問題,調(diào)試就很困難。

UCS(Universal Multiple Octet Coded Character Set)標準的制定,讓開發(fā)人員遠離混亂的多字節(jié)字符集。UCS標準里,所有的字符都有唯一的碼點(Code Point),根據(jù)碼點就可查到對應字符。UCS用兩個字節(jié)表示一個碼點(UCS-4標準是4個字節(jié)),對應一個字符。由于使用了兩個字節(jié),可容納2^16-1(6w+)字符,基本上容下各國常用的字符(UCS-4理論上可容納上二十億個字符,目前收納超過16W個字符)。注意UCS只是一個標準,規(guī)定了碼點與字符的一一對應關系,但沒有定義如何存儲在計算機中。

規(guī)定Unicode字符存儲方式的工作由UTF(Unicode Transformation Format)完成,應用最多的方案是UTF-16和UTF-8。UTF-16使用兩個字節(jié)表示一個字符,Windows, MacOS, Java平臺默認的字符編碼方案都是UTF-16。由于有兩個字節(jié),便存在大端和小端兩種方案的區(qū)分。只有ASCII字符的文件,使用UTF-16編碼存在空間浪費嚴重的現(xiàn)象(浪費50%的存儲),由Ken Thompson(C語言發(fā)明人)和Robe Pike(Go語言發(fā)明人)提出的UTF-8編碼方案很快流行起來。UTF-8是單字節(jié)流,不存在字節(jié)序問題,也不需要BOM。目前UTF-8是web通行標準。

對應關系

USC-2的取值范圍是U+0000~U+FFFF,與UTF-8的對應關系如下:

十六進制 二進制
0000 0000-0000 007F 0xxxxxxx
0000 0080-0000 07FF 110xxxxx 10xxxxxx
0000 0800-0000 FFFF 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

從編碼可以看出,與二進制相比,浪費了很多空間。不過這也沒辦法,可顯示的字符更容易閱讀和理解,人類很難抗拒這個誘惑。

UTF-8轉(zhuǎn)換規(guī)則為: 1. 如果某字節(jié)第一位是 0 ,那么判定為 ASCII 字節(jié),除了 0 外余下的 7 位是 ASCII 碼,所以 UTF-8 是兼容 ASCII 碼的; 2. 如果第一個字節(jié)是 1 ,那么連續(xù)的幾個 “1” 代表從這個字符開始,后面連續(xù)的幾個字節(jié)其實是一個字位,且后面的字節(jié)都要以10開頭。

了解如上規(guī)則,我們的程序便可輕松的處理UTF-8編碼的字節(jié)流。例如要找出“中”的UTF-8編碼,則可以這樣處理(注意文件是UTF-8編碼):

$char = "中";
$length = strlen($char);
$bytes = pack("a" . $length, $char);
echo "UTF-8:" . bin2hex($bytes) . "
";

// 或者
echo "UTF-8:";
for ($index = 0; $index < $length; ++ $index) {
    echo bin2hex($char{$index});
}
echo PHP_EOL;

也可以寫出針對UTF-8編碼的strlen函數(shù):

function myStrlen(string $string)
{
    $slen = strlen($string);
    $mlen = 0;
    $maxByteLength = 4;
    $maxOffset = 7;
    for ($i = 0; $i < $slen; ++ $i) {
        $byte = ord($string{$i});
        // 從01xxxxxx開始對比,直到11110xxxx 10xxxxxx 10xxxxxx 10xxxxxx。只需要對比第一個字節(jié)即可
        for ($offset = 0; $offset < $maxByteLength; ++ $offset) {
            $result = $byte & (1 << ($maxOffset - $offset));
            if ($result === 0) {
                $i += $offset;
                ++ $mlen;
                break;
            }
        }
    }

    return $mlen;
}

$string = "Coder不是工程師!";
echo "mb_strlen:" . mb_strlen($string) . "
";
echo "mStrlen:" . myStrlen($string) . "
";

了解其原理,亂碼不再困惑和迷茫。

參考

https://www.cs.umd.edu/class/...

http://www.unicode.org/faq/ut...

https://my.oschina.net/goal/b...

http://mp.weixin.qq.com/s/2H6...

https://www.lifewire.com/file...

文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/28373.html

相關文章

  • Linux下文件名長度限制

    摘要:下文件名長度限制出現(xiàn)場景在迭代中有一個需求是將文件名修改為所有班級的名稱集合,出現(xiàn)的班級過多導致的文件名過長在下無法創(chuàng)建文件和文件夾的情況解決方式經(jīng)過查證,中文件名最長為字符,文件路徑最大長度為字符。這是被編碼方案決定的,通過來指定。 Linux下文件名長度限制 出現(xiàn)場景:在迭代中有一個需求是將pdf文件名修改為所有班級的名稱集合,出現(xiàn)的班級過多導致的文件名過長在linux下無法創(chuàng)建文...

    entner 評論0 收藏0
  • 徹底理解編碼

    摘要:只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。比如中國就制定了等編碼規(guī)范。 只要涉及編程工作,編碼是永遠繞不開的問題。只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。下面是我對編碼的...

    guyan0319 評論0 收藏0
  • 徹底理解編碼

    摘要:只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。比如中國就制定了等編碼規(guī)范。 只要涉及編程工作,編碼是永遠繞不開的問題。只有徹底理解編碼,遇到編碼問題才知道問題的根源在哪里,并找到對應的解決辦法?;ㄒ稽c時間去徹底消化并理解他,長遠來看,對以后工作效率的提升是非常值得的。下面是我對編碼的...

    leoperfect 評論0 收藏0
  • 前后端交互過程中的編碼

    摘要:前后端交互過程中涉及的編碼首先,瀏覽器的設置里有設置編碼格式,一般設置為。按照設置的順序檢查檢測文件的編碼。 起因 最近在寫PHP,本身對PHP不太熟練。然后遇到編碼這個問題,困擾了大半天,索性,系統(tǒng)探索解決一番。 前后端交互過程中涉及的編碼 Browser cilent: 首先,瀏覽器的設置里有設置編碼格式,一般設置為UTF-8。 AJAX request: AJAX異步請求的過程...

    William_Sang 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<