OC 字符串編碼-中英文字符串混合長度

1.各種編碼格式 原理以及發(fā)展歷史

1.1 ASCII碼

早起計(jì)算機(jī)發(fā)展初期,肯定是以字母為標(biāo)準(zhǔn)的,沒考慮世界上其他語言 如中文,日文韓文等,故此起初設(shè)計(jì)的字符集合也就比較簡(jiǎn)單,也就是如今的ASCII碼。
ASCII碼一共規(guī)定了128個(gè)字符的編碼,比如大寫的字母A是65(二進(jìn)制01000001)。這128個(gè)符號(hào)(包括32個(gè)不能打印出來的控制符號(hào)),只占用了一個(gè)字節(jié)的后面7位,最前面的1位統(tǒng)一規(guī)定為0。

1.2. 非ASCII碼

英語用128個(gè)符號(hào)編碼就夠了,但是用來表示其他語言,128個(gè)符號(hào)是不夠的。比如,在法語中,字母上方有注音符號(hào),它就無法用ASCII碼表示。需要擴(kuò)展編碼集合有些就使用ASCII碼保留碼有些,有些就使用兩個(gè)字節(jié)來表示如國標(biāo)GB2312就是兩個(gè)字節(jié)表示一個(gè)漢字。但是各個(gè)地區(qū)國家各自為政發(fā)展出來了很多不同的非ASCII碼體系,如臺(tái)灣與大陸編碼都不一樣,這導(dǎo)致溝通成本很大,故此迫切需要一個(gè)標(biāo)準(zhǔn)化的符號(hào)集合,Unicode孕育而生。

1.3.Unicode

Unicode只是一個(gè)符號(hào)集合,規(guī)定了二進(jìn)制代碼,但是并沒規(guī)定具體存儲(chǔ)方式。
對(duì)應(yīng)具體的漢字有可能其Unicode需要二個(gè)字節(jié)來保存其轉(zhuǎn)換出來的二進(jìn)制數(shù),也有可能需要3個(gè)字節(jié),4個(gè)字節(jié)才能夠保存,大部分漢字是需要4個(gè)字節(jié)來表示。
比如,漢字“嚴(yán)”的unicode是十六進(jìn)制數(shù)4E25,轉(zhuǎn)換成二進(jìn)制數(shù)足足有15位(100111000100101),也就是說這個(gè)符號(hào)的表示至少需要2個(gè)字節(jié)。表示其他更大的符號(hào),可能需要3個(gè)字節(jié)或者4個(gè)字節(jié),甚至更多。

這里就有兩個(gè)嚴(yán)重的問題,第一個(gè)問題是,如何才能區(qū)別unicode和ascii?計(jì)算機(jī)怎么知道三個(gè)字節(jié)表示一個(gè)符號(hào),而不是分別表示三個(gè)符號(hào)呢?第二個(gè)問題是,我們已經(jīng)知道,英文字母只用一個(gè)字節(jié)表示就夠了,如果unicode統(tǒng)一規(guī)定,每個(gè)符號(hào)用三個(gè)或四個(gè)字節(jié)表示,那么每個(gè)英文字母前都必然有二到三個(gè)字節(jié)是0,這對(duì)于存儲(chǔ)來說是極大的浪費(fèi),文本文件的大小會(huì)因此大出二三倍,這是無法接受的。

它們?cè)斐傻慕Y(jié)果是:1)出現(xiàn)了unicode的多種存儲(chǔ)方式,也就是說有許多種不同的二進(jìn)制格式,可以用來表示unicode。2)unicode在很長一段時(shí)間內(nèi)無法推廣,直到互聯(lián)網(wǎng)的出現(xiàn)。

1.4.UTF-8
UTF-8是Unicode的實(shí)現(xiàn)方式之一,其他實(shí)現(xiàn)方式還包括UTF-16和UTF-32,不過在互聯(lián)網(wǎng)上基本不用。
互聯(lián)網(wǎng)的普及,人們的快去要溝通越來越頻繁,強(qiáng)烈要求出現(xiàn)一種統(tǒng)一的編碼方式,UTF-8就此誕生。

UTF-8最大的一個(gè)特點(diǎn),就是它是一種變長的編碼方式。它可以使用1~4個(gè)字節(jié)表示一個(gè)符號(hào),根據(jù)不同的符號(hào)而變化字節(jié)長度。

UTF-8的編碼規(guī)則很簡(jiǎn)單,只有二條:
1)對(duì)于單字節(jié)的符號(hào),字節(jié)的第一位設(shè)為0,后面7位為這個(gè)符號(hào)的unicode碼。因此對(duì)于英語字母,UTF-8編碼和ASCII碼是相同的。
2)對(duì)于n字節(jié)的符號(hào)(n>1),第一個(gè)字節(jié)的前n位都設(shè)為1,第n+1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進(jìn)制位,全部為這個(gè)符號(hào)的unicode碼。

UTF-8 每字至少 1 byte,至多 4 bytes。1 byte 字符與 US-ASCII 相符。U+0800-07ff 是 2 bytes,0800-ffff 是 3 bytes,之后的是 4 bytes

下表總結(jié)了編碼規(guī)則,字母x表示可用編碼的位。
Unicode符號(hào)范圍 | UTF-8編碼方式

image.png

下面,還是以漢字“嚴(yán)”為例,演示如何實(shí)現(xiàn)UTF-8編碼。
已知“嚴(yán)”的unicode是4E25(100111000100101),根據(jù)上表,可以發(fā)現(xiàn) 4E25處在第三行的范圍內(nèi)(0000 0800-0000 FFFF),因此“嚴(yán)”的UTF-8編碼需要三個(gè)字節(jié),即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,從“嚴(yán)”的最后一個(gè)二進(jìn)制位開始,依次從后向前填入格式中的x,多出的位補(bǔ)0。這樣就得到了,“嚴(yán)”的UTF-8編碼是 “11100100 10111000 10100101”,轉(zhuǎn)換成十六進(jìn)制就是E4B8A5。

2.實(shí)際使用場(chǎng)景

2.1 需求:求中英文混合長度

從上可做字符串的長度取決于我們的字符編碼方式,如國標(biāo)GB2312那就一個(gè)漢字兩個(gè)字節(jié),字母一個(gè)字節(jié),如UTF-8,一個(gè)漢字是動(dòng)態(tài)的長度2個(gè)字節(jié)到4個(gè)字節(jié)之間,千萬別再說一個(gè)漢字在UTF-8這種unicode實(shí)現(xiàn)方式上是3個(gè)字節(jié)了,日韓字符集合是四個(gè)字節(jié),當(dāng)然常用的中文大部分落在3個(gè)字節(jié)范圍內(nèi)。所以說標(biāo)準(zhǔn)的約定很重要,客戶端內(nèi)部的約定,客戶端與服務(wù)器端的約定。只有形成了標(biāo)準(zhǔn)才能交流實(shí)現(xiàn)??蛻舳伺c服務(wù)器端標(biāo)準(zhǔn)不同話,各自算出的長度都不一樣,如某些場(chǎng)景需要截?cái)嘧址?,那么就容易出問題了,客戶端明明告訴服務(wù)器端截取多少個(gè),可因?yàn)闃?biāo)準(zhǔn)的不同多截了或者少截了,導(dǎo)致一些bug。

  NSString * text = @"1234劉a";
  NSInteger length = [text length]; //length值為6,length僅僅返回字符個(gè)數(shù)而不是存儲(chǔ)空間大小
  NSInteger length_utf8 = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding]; //length_utf8值為8

  NSString * text1 = @"劉";
  NSInteger length_utf8 = [text lengthOfBytesUsingEncoding:NSUTF8StringEncoding];//length_utf8值為3

可見在NSUTF8StringEncoding存儲(chǔ)形式下的unicode,中文“劉”字,占存儲(chǔ)空間為3個(gè)字節(jié),字符與數(shù)字均為一個(gè)字節(jié)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 字符集和編碼簡(jiǎn)介 在編程中常??梢砸姷礁鞣N字符集和編碼,包括ASCII,MBCS,Unicode等字符集。確切的說...
    蘭山小亭閱讀 9,100評(píng)論 0 13
  • 童年好遙遠(yuǎn) 回憶斷了片 1 在農(nóng)村長大的我們,沒有機(jī)會(huì)體驗(yàn)托兒所、幼兒園的多彩生活,但是我們有我們的小天地。前一天...
    晨曦問早閱讀 324評(píng)論 3 5

友情鏈接更多精彩內(nèi)容