從Emoji的限制到Unicode編碼

某一天伏穆,leader找到我說(shuō)宇植,felix啊,這里有個(gè)小需求,給我們的實(shí)名認(rèn)證中的地址加入字?jǐn)?shù)限制埃儿,一天時(shí)間綽綽有余了吧。我一聽(tīng)册踩,小事啊工闺,趕緊拍拍胸脯告訴leader,一天都不用温峭,以我的效率1個(gè)小時(shí)就夠了猛铅。領(lǐng)導(dǎo)很滿意的說(shuō),小伙子有前途凤藏。

那些年的Emoji

打開(kāi)工程奸忽,三下五除二就定位到修改點(diǎn)修改完畢,自測(cè)通過(guò)揖庄,完美栗菜。就在我美滋滋的沖上一杯咖啡,幻想年底能不能拿個(gè)5星員工蹄梢,走上人生巔峰的時(shí)候疙筹,測(cè)試妹子找到了我:
『felix你代碼有問(wèn)題,如果最后的字符是emoji表情禁炒,會(huì)被截?cái)喽亍!?br> what齐苛?作為一名老資歷程序員翘盖,我自然考慮過(guò)不同字符的問(wèn)題,最典型的就是中英文混排凹蜂。但在這種情況下馍驯,NSString返回的字符長(zhǎng)度是相同的阁危,想來(lái)是蘋(píng)果爸爸幫我們處理好了√保可這emoji的長(zhǎng)度是什么鬼狂打?
我趕緊寫(xiě)了個(gè)代碼,測(cè)試了下emoji的長(zhǎng)度混弥。

NSString *a = @"??";
NSLog(@"%d",a.length);

結(jié)果是

2

這下我只好趕緊找找unicode的資料趴乡。

從ASCII的榮光到Unicode的崛起

程序員都知道,計(jì)算機(jī)沒(méi)法直接處理文本蝗拿,它只和數(shù)字打交道晾捏。為了在計(jì)算機(jī)里用數(shù)字表示文本,我們指定了一個(gè)從字符到數(shù)字的映射哀托。這個(gè)映射就叫做編碼(encoding)惦辛。最有名的一個(gè)字符編碼是 ASCII。ASCII 碼是 7 位的仓手,它將英文字母胖齐,數(shù)字 0-9 以及一些標(biāo)點(diǎn)符號(hào)和控制字符映射為 0-127 這些整型。但是嗽冒,由于 8 位的空間對(duì)于歐洲的文字來(lái)說(shuō)都不夠呀伙,更不用說(shuō)全世界的書(shū)寫(xiě)系統(tǒng)了,因此人們開(kāi)發(fā)了更加通用的編碼——Unicode添坊。最初剿另,Unicode 編碼是被設(shè)計(jì)為 16 位的,提供了 65,536 個(gè)字符的空間帅腌。當(dāng)時(shí)人們認(rèn)為這已經(jīng)大到足夠編碼世界上現(xiàn)代文本里所有的文字和字符了驰弄。后來(lái),考慮到要編碼歷史上的文字以及一些很少使用的日本漢字和中國(guó)漢字[^2]速客,Unicode 編碼擴(kuò)展到了 21 位(從 U+0000 到 U+10FFFF)。

Unicode編碼空間

Unicode 的基本元素 —— 它的 “字符”五鲫,雖然這種叫法不是太貼切——被稱作編碼點(diǎn)(Code Point)溺职。編碼點(diǎn)通過(guò)數(shù)字來(lái)區(qū)分,通常寫(xiě)成 16 進(jìn)制的形式再加前綴“U+”位喂,例如 U+0041 表示拉丁字母 “A” 浪耘、U+03B8 表示 希臘字母 “θ”。所有編碼點(diǎn)組成的集合被稱作編碼空間(Code Space)塑崖。
Unicode 編碼空間包含 1,114,112 個(gè)編碼點(diǎn)七冲。然而,其中只有128,237 個(gè)編碼點(diǎn) —— 編碼空間的 12% 被賦值规婆,目前澜躺。還有很多空間用來(lái)增長(zhǎng)蝉稳!Unicode 還保留了另外 137,468 字符 作為 “自用” 空間,這些字符沒(méi)有標(biāo)準(zhǔn)的含義掘鄙,可以被個(gè)人應(yīng)用所使用耘戚。
為了對(duì)編碼空間的布局有個(gè)了解,把它可視化會(huì)比較直觀操漠。下面是整個(gè)編碼空間的布局收津,一個(gè)像素代表一個(gè)編碼點(diǎn)。使用小方塊來(lái)表示以保證視覺(jué)的一致性浊伙;每個(gè)小方塊是 16×16 = 256 個(gè)編碼點(diǎn)撞秋,每個(gè)大方塊是一個(gè)面有 65536 個(gè) 編碼點(diǎn)∠桑總共加起來(lái)有 17 個(gè)面板吻贿。


Unicode空間表
  • 白色表示未用空間;
  • 藍(lán)色表示已用空間拗慨;
  • 綠色表示自用區(qū)域廓八;
  • 小的紅色區(qū)域是代理區(qū)(surrogates,后面會(huì)講)赵抢。
    其中第一個(gè)面板被稱作『基本多語(yǔ)言面板(Basic Multilingual Plane剧蹂,簡(jiǎn)稱 BMP)』。BMP包含現(xiàn)代文本所需的基本所有字符烦却,包括拉丁文宠叼、斯拉夫文、希臘文其爵、漢字(中國(guó))冒冬,日文、朝鮮文摩渺、阿拉伯文简烤、希伯來(lái)文、梵文(印度)等等摇幻。這個(gè)面板就是最初Unicode設(shè)計(jì)所占用的空間(16位横侦,65536個(gè)字符)。后來(lái)擴(kuò)展到現(xiàn)在這個(gè)規(guī)模绰姻,然而枉侧,大部分現(xiàn)代字符在BMP的范圍內(nèi)。
    第二個(gè)面板則是包括歷史上的文字狂芋,比如蘇美爾楔形文字和埃及象形文字還有今天我們說(shuō)起的emoji表情榨馁。第三個(gè)面板包含一大塊不常用的和歷史上的漢字字符。剩下的是空的帜矾,除了 倒數(shù)第三個(gè)面板中有一小部分被用作格式化字符翼虫;倒數(shù)兩個(gè)面板全部保留自用屑柔。
    為了和以前的ASCII編碼兼容,Unicode的128個(gè)字符就是ASCII的拷貝蛙讥。這樣很容易從小編碼轉(zhuǎn)向unicode锯蛀。順帶提一句,由于unicode被設(shè)計(jì)為以抽象的方式戴表一個(gè)字符次慢,而不規(guī)定這個(gè)字符如何呈現(xiàn)旁涤。如此一來(lái),Unicode 對(duì)中文迫像、日文和韓文(CJK)里使用的漢字(也就是所謂的統(tǒng)一漢字)都使用完全相同的碼點(diǎn)(這一決定頗具爭(zhēng)議)劈愚,盡管在這些書(shū)寫(xiě)系統(tǒng)里,每個(gè)漢字都發(fā)展出了獨(dú)特的字形變體闻妓。

UTF8和UTF16

現(xiàn)在搞懂了Unicode的編碼點(diǎn)了菌羽,但是在內(nèi)存或文件中如何用字節(jié)表示呢?
當(dāng)然由缆,最省事的辦法就是用32位來(lái)存儲(chǔ)編碼點(diǎn)下標(biāo)注祖,但是這樣的話,每個(gè)字符都占四個(gè)字節(jié)均唉,當(dāng)你處理大量文本的時(shí)候是晨,這樣就太浪費(fèi)內(nèi)存或帶寬了。
在我們討論解決辦法之前舔箭,我們先看看一個(gè)圖:


使用頻率

這是unicode編碼面板中的前三個(gè)面板的使用頻率圖(數(shù)據(jù)來(lái)自維基百科和twitter)罩缴。頻率增長(zhǎng)的方向是黑(沒(méi)出現(xiàn))、紅层扶、黃箫章、白。
可以看到镜会,絕大多數(shù)文本分布在BMP內(nèi)檬寂,有些零散的使用來(lái)自第二三個(gè)面板。第二個(gè)面板下高頻率使用的字符則是部分emoji表情戳表。
那么焰薄,為了解決unicode編碼占據(jù)的內(nèi)存問(wèn)題,unicode就有了幾個(gè)緊湊的編碼 扒袖。32 位整數(shù)編碼被稱作 UTF-32(UTF=”Unicode Transformation Format”),但是很少被用來(lái)存儲(chǔ)亩码。最常見(jiàn)的是季率,你會(huì)看到 Unicode 文本被編碼為 UTF-8 或 UTF-16。從上面的熱力圖可知兩個(gè)編碼涵蓋的是最常見(jiàn)的文本描沟,內(nèi)存能最大程度的利用飒泻。這些都是可變長(zhǎng)度編碼鞭光,分別由 8-bit 或 16-bit 為一個(gè)單元組成。這些方案中泞遗,下標(biāo)值較小的編碼點(diǎn)占用的字節(jié)數(shù)也少惰许,會(huì)節(jié)省不少內(nèi)存。這樣做的代價(jià)是處理 UTF-8/16 需要以編程的方式來(lái)處理史辙,會(huì)慢一些汹买。

1. UTF8

在 UTF-8 中,每個(gè)編碼點(diǎn)依據(jù)下標(biāo)值聊倔,被存儲(chǔ)為 1 到 4 個(gè)字節(jié)晦毙。
UTF-8 使用二進(jìn)制前綴系統(tǒng),在此系統(tǒng)中每個(gè)字符的最高位的幾個(gè)比特表明它是否是單個(gè)字節(jié)耙蔑,多字節(jié)序列的開(kāi)始见妒,或中間字節(jié);剩余的比特連接起來(lái)表示編碼點(diǎn)的下標(biāo)甸陌。下面的表格展示了UTF-8 是如何編碼的:

UTF-8 (二進(jìn)制) 編碼點(diǎn) (二進(jìn)制) 范圍
110xxxxx 10yyyyyy xxxxxyyyyyy U+0080–U+07FF
1110xxxx 10yyyyyy 10zzzzzz xxxxyyyyyyzzzzzz U+0800–U+FFFF
11110xxx 10yyyyyy 10zzzzzz 10wwwwww xxxyyyyyyzzzzzzwwwwww U+10000–U+10FFFF

UTF8有以下幾個(gè)好處:

  • 對(duì)于很常見(jiàn)的西文字符须揣,采用這種編碼方式也不會(huì)浪費(fèi)內(nèi)存。
  • 由于UTF-8 是基于 8 位的碼元的钱豁,因此它并不需要關(guān)心字節(jié)順序耻卡。
  • 任何已經(jīng)是 ASCII 編碼的字符串和文件無(wú)需轉(zhuǎn)換就可以被 UTF-8 識(shí)別。
  • 大量的廣泛使用的編程慣例——比如 NULL 結(jié)尾寥院,分隔符(n,t,’,’,”)等——在 UTF-8 中也是可用的劲赠。
    其中,后面這兩點(diǎn)好處是基于UTF8的一個(gè)屬性秸谢,即最開(kāi)始128 個(gè)字符(ASCII字符)被編碼為單個(gè)字節(jié)凛澎,所有的非 ASCII 字符被編碼為 128-255。

因?yàn)檫@些原因估蹄,UTF-8 成為存儲(chǔ)和交流 Unicode 文本方面的最佳編碼塑煎。它也已經(jīng)是文件格式、網(wǎng)絡(luò)協(xié)議以及 Web API 領(lǐng)域里事實(shí)上的標(biāo)準(zhǔn)了臭蚁。這也是為什么我們?cè)谔幚碜址畷r(shí)最铁,最常打交道的是NSUTF8StringEncoding

2. UTF16

和 UTF-8 一樣垮兑,我們可以用二進(jìn)制前綴的形式表示 UTF-16 的編碼規(guī)則:

UTF-16 (二進(jìn)制) 編碼點(diǎn) (二進(jìn)制) 范圍
xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx U+0000–U+FFFF
110110xxxxxxxxxx 110111yyyyyyyyyy xxxxxxxxxxyyyyyyyyyy + 0x10000 U+10000–U+10FFFF

正如我們前面所言冷尉,最早unicode是設(shè)計(jì)為16位,包含的范圍也就是BMP系枪。但后來(lái)為了支持一些更少使用的漢字或其它字符雀哨,unicode擴(kuò)展到21位。為了在UTF16中能訪問(wèn)到后面的碼位,這些碼位會(huì)被編碼為一對(duì)16bit的碼元雾棺,稱作代理對(duì)膊夹。具體方法可以參考維基百科。由于BMP剩下可用來(lái)做代理的范圍僅剩U+D800-U+DFFF中的編碼點(diǎn)捌浩,1位用于標(biāo)識(shí)高位或低位放刨,剩下的10位成對(duì)最多只能支持到220-1 ,所以u(píng)nicode只能擴(kuò)展到21位(最大值220 + 216 -1)尸饺。
同時(shí)由于UTF16被設(shè)計(jì)為多字節(jié)进统,和所有多字節(jié)長(zhǎng)度的編碼系統(tǒng)一樣,它還得解決字節(jié)順序的問(wèn)題侵佃。Unicode 在這個(gè)問(wèn)題上沒(méi)有說(shuō)明麻昼,雖然它確實(shí)鼓勵(lì)一個(gè)慣例,即把 U+FEFF 零寬無(wú)間斷間隔這個(gè)字符放到 UTF-16 文件開(kāi)頭作為字節(jié)序標(biāo)識(shí)馋辈,來(lái)消除字節(jié)序問(wèn)題抚芦。

An NSString object encodes a Unicode-compliant text string, represented as a sequence of UTF–16 code units. All lengths, character indexes, and ranges are expressed in terms of UTF–16 code units, with index values starting at 0. The length property of an NSString returns the number of UTF-16 code units in an NSString, and the characterAtIndex: method retrieves a specific UTF-16 code unit. These two "primitive" methods provide basic access to the contents of a string object.
在iOS系統(tǒng)中,NSString是以UTF16編碼的迈螟,默認(rèn)是大端字節(jié)序叉抡,如果要使用其它字節(jié)序,則需要使用NSUTF16BigEndianStringEncoding或者NSUTF16LittleEndianStringEncoding答毫。(注:蘋(píng)果同時(shí)還提供了NSUTF32BigEndianStringEncoding和NSUTF32LittleEndianStringEncoding)

組合字符

看完這些資料褥民,我自信對(duì)Unicode的編碼方式相當(dāng)了解了。長(zhǎng)度不同的問(wèn)題是因?yàn)榫幋a不同嘛洗搂,所以我直接取字符串的32位編碼長(zhǎng)度消返,就沒(méi)問(wèn)題了。于是代碼修改如下:

NSString *a = @"??";
NSLog(@"%d",[test lengthOfBytesUsingEncoding:NSUTF32StringEncoding]/4);

結(jié)果是:

1

完美耘拇!關(guān)單讓測(cè)試小姐姐重測(cè)下撵颊,我又可以繼續(xù)喝我的咖啡了。然而惫叛,我才喝了一口倡勇,測(cè)試小姐姐反饋說(shuō)還是有問(wèn)題。

無(wú)奈嘉涌,我只能放下我的咖啡妻熊,根據(jù)測(cè)試小姐姐的反饋,重新調(diào)試下:

NSString *a = @"????";
NSLog(@"%d",[test lengthOfBytesUsingEncoding:NSUTF32StringEncoding]/4);

調(diào)試結(jié)果:

2

這不科學(xué)奥刈睢扔役!明明unicode都是32位,咋一個(gè)字符還長(zhǎng)度為2了呢警医。

組合字符

繼續(xù)沉浸在unicode的大部頭中厅目,我終于找到了新的信息——組合字符。
Unicode 包含一個(gè)系統(tǒng),可以合并多個(gè)編碼點(diǎn)损敷,動(dòng)態(tài)組合字符。此系統(tǒng)用各種方式增加靈活性深啤,而不引起編碼點(diǎn)的巨大組合膨脹拗馒。
例如,在歐洲語(yǔ)言中溯街,組合標(biāo)記出現(xiàn)在變音符和字母的使用中诱桂。 Unicode 支持各種各樣的變音符號(hào),包括尖音符號(hào)的和重音符號(hào)呈昔、元音變音符號(hào)挥等、變音符號(hào)等等。所有這些變音符可以被使用在任何字母表的字母中堤尾。事實(shí)上肝劲,多個(gè)變音符號(hào)可以被使用在一個(gè)字母上。
如果 Unicode 試圖為每個(gè)字母組合或變音符組合分配一個(gè)獨(dú)立的編碼點(diǎn)郭宝,事情會(huì)變得無(wú)法控制辞槐。相反,動(dòng)態(tài)組合系統(tǒng)可以讓你構(gòu)造你想要的任何字符粘室,通過(guò)以一個(gè)基礎(chǔ)編碼點(diǎn)(字母)開(kāi)始然后附加額外的編碼點(diǎn)榄檬,被稱作“組合標(biāo)識(shí)”,來(lái)指定變音符衔统。當(dāng)一個(gè)文字渲染器看到字符串中有這樣的序列時(shí)鹿榜,它會(huì)自動(dòng)堆疊變音符到基礎(chǔ)字母的上面或下面來(lái)造出一個(gè)組合字符。
例如锦爵,帶重音的字符“á” 會(huì)被表示成由兩個(gè)編碼點(diǎn)組成的字符串:U+0041 “A” 拉丁大寫(xiě)字母 a 加上 U+0301 “??”組合尖音符號(hào)舱殿。這個(gè)字符串自動(dòng)被渲染成單個(gè)字符:“á”。

有時(shí)候我們會(huì)看到某些人的簽名中有很奇怪的字符棉浸,其實(shí)他們就是利用了組合字符怀薛。比如á?? 就是多添加了幾個(gè)尖音符號(hào):U+0041U+0301U+0301U+0301

如今,Unicode 還包含許多 “預(yù)設(shè)的” 編碼點(diǎn)迷郑,每個(gè)表示一個(gè)被使用過(guò)的組合枝恋,例如 U+00C1 “á” 帶銳音符的拉丁大寫(xiě)字母A 或 U+1EC7 “?” 帶揚(yáng)抑符和下點(diǎn)的小寫(xiě)拉丁字母 e。我懷疑這些大多繼承自融入 Unicode 的舊編碼嗡害,來(lái)保證兼容性焚碌。實(shí)際上,對(duì)于歐洲語(yǔ)言中的大多數(shù)常見(jiàn)的帶變音符號(hào)的字母都有預(yù)設(shè)霸妹,所以文本中動(dòng)態(tài)組合用的不多十电。
Unicode 中,預(yù)設(shè)字符和動(dòng)態(tài)組合系統(tǒng)并存。后果就是有多種方法表示同一個(gè)字符串——不同編碼點(diǎn)序列產(chǎn)生相同用戶可感知的字符鹃骂。例如台盯,我們之前看到的,表示字符 “á”畏线,我們可以用一個(gè)編碼點(diǎn) U+00C1 静盅,也可以用兩個(gè)編碼點(diǎn) U+0041 和U+0301。要解決這個(gè)等值字符串的問(wèn)題寝殴,Unicode 定義了幾種形式正規(guī)化方法蒿叠。比如NFD和NFC,由于這部分比較復(fù)雜就不做贅述蚣常。有興趣的可以參考后面提供的資料市咽。

字位簇

如上所見(jiàn),Unicode 包含多種情況抵蚊,用戶認(rèn)為的一個(gè)“字符” 事實(shí)上底下可能由多個(gè)編碼點(diǎn)組成施绎。Unicode 使用「字位簇」的概念來(lái)表示這種情況。一個(gè)由一個(gè)或多個(gè)編碼點(diǎn)組成的字符串構(gòu)成一個(gè) “用戶感知的字符”泌射。
UAX #29 為字位簇定義了精確的規(guī)則粘姜。它大約是 “一個(gè)基本的編碼點(diǎn)接著任意數(shù)量的組合標(biāo)記”,但是真實(shí)的定義有點(diǎn)復(fù)雜熔酷;它包含了朝鮮語(yǔ)字母孤紧,和 emoji ZWJ 序列。
所以拒秘,部分emoji的unicode長(zhǎng)度大于1的本質(zhì)原因是這些emoji是字位簇号显。具體的emoji列表可以查看這個(gè)網(wǎng)址√删疲可以看到蘋(píng)果爸爸在后面添加的很多emoji長(zhǎng)度已經(jīng)不是單個(gè)unicode字符了押蚤。畢竟一個(gè)emoji表情還要?jiǎng)澐秩朔N這種喪心病狂的事情,再多碼位也hold不住羹应。

終極解決方案

本來(lái)如果只是不同unicode編碼的問(wèn)題揽碘,那么統(tǒng)一使用UTF32就可以了。但由于組合字符的存在园匹,一個(gè)人類(lèi)可讀的字符串在編碼中實(shí)際上是一個(gè)稀疏陣列雳刺。先不說(shuō)如何處理那么多種語(yǔ)言下的組合字符的問(wèn)題,單是處理這個(gè)陣列找出真正的可讀字符串也是需要好些代碼裸违。還好掖桦,iOS下提供了一個(gè)方法enumerateSubstringsInRange:options:usingBlock:可以方便的找出迭代找出字符串中的組合字符。那么判斷一個(gè)字符串實(shí)際長(zhǎng)度的做法是:

    NSMutableArray *characters = [NSMutableArray array];
    NSString *test = @"??????♂???????????";
    [test enumerateSubstringsInRange:NSMakeRange(0, test.length) options:NSStringEnumerationByComposedCharacterSequences usingBlock:^(NSString * _Nullable substring, NSRange substringRange, NSRange enclosingRange, BOOL * _Nonnull stop) {
        [characters addObject:substring];
    }];
    NSLog(@"%ld",characters.count);

結(jié)果正確供汛。這里還需要考慮到枪汪,如果是要截取字符串涌穆,那么要?jiǎng)h除的部分,也應(yīng)該是完整的組合字符雀久。這里就不寫(xiě)具體的代碼宿稀,留給大家做作業(yè)~~~

結(jié)尾

實(shí)際上unicode還有很多復(fù)雜的內(nèi)容,還在很多問(wèn)題都已經(jīng)由系統(tǒng)幫我們處理好了岸啡。但是了解unicode的機(jī)制原叮,對(duì)于我們解決bug有很大的幫助。

此文是根據(jù)以下文章重新整理而成:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末巡蘸,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子擂送,更是在濱河造成了極大的恐慌悦荒,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件嘹吨,死亡現(xiàn)場(chǎng)離奇詭異搬味,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)蟀拷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)碰纬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人问芬,你說(shuō)我怎么就攤上這事悦析。” “怎么了此衅?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,764評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵强戴,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我挡鞍,道長(zhǎng)骑歹,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,193評(píng)論 1 292
  • 正文 為了忘掉前任墨微,我火速辦了婚禮道媚,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翘县。我一直安慰自己最域,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布炼蹦。 她就那樣靜靜地躺著羡宙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪掐隐。 梳的紋絲不亂的頭發(fā)上狗热,一...
    開(kāi)封第一講書(shū)人閱讀 51,182評(píng)論 1 299
  • 那天钞馁,我揣著相機(jī)與錄音,去河邊找鬼匿刮。 笑死僧凰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熟丸。 我是一名探鬼主播训措,決...
    沈念sama閱讀 40,063評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼光羞!你這毒婦竟也來(lái)了绩鸣?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,917評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤纱兑,失蹤者是張志新(化名)和其女友劉穎呀闻,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體潜慎,經(jīng)...
    沈念sama閱讀 45,329評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捡多,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了铐炫。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片垒手。...
    茶點(diǎn)故事閱讀 39,722評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖倒信,靈堂內(nèi)的尸體忽然破棺而出科贬,到底是詐尸還是另有隱情,我是刑警寧澤堤结,帶...
    沈念sama閱讀 35,425評(píng)論 5 343
  • 正文 年R本政府宣布唆迁,位于F島的核電站,受9級(jí)特大地震影響竞穷,放射性物質(zhì)發(fā)生泄漏唐责。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評(píng)論 3 326
  • 文/蒙蒙 一瘾带、第九天 我趴在偏房一處隱蔽的房頂上張望鼠哥。 院中可真熱鬧,春花似錦看政、人聲如沸朴恳。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,671評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)于颖。三九已至,卻和暖如春嚷兔,著一層夾襖步出監(jiān)牢的瞬間森渐,已是汗流浹背做入。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,825評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留同衣,地道東北人竟块。 一個(gè)月前我還...
    沈念sama閱讀 47,729評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像耐齐,于是被迫代替她去往敵國(guó)和親浪秘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 字符是用戶可以讀寫(xiě)的最小單位。計(jì)算機(jī)所能支持的字符組成的集合辕翰,就叫做字符集违帆。字符集通常以二維表的形式存在。二維表的...
    劉惜有閱讀 8,109評(píng)論 2 14
  • UTF-8 編碼提供了一種簡(jiǎn)便而向后兼容的方法, 使得那種完全圍繞 ASCII 設(shè)計(jì)的操作系統(tǒng), 比如 Unix,...
    謝大見(jiàn)閱讀 4,695評(píng)論 0 3
  • 轉(zhuǎn)載自O(shè)bjeC中國(guó) 歷史 計(jì)算機(jī)沒(méi)法直接處理文本金蜀,它只和數(shù)字打交道。為了在計(jì)算機(jī)里用數(shù)字表示文本的畴,我們指定了一個(gè)...
    玉米包谷閱讀 1,179評(píng)論 0 4
  • 在當(dāng)前這個(gè)時(shí)代(比如說(shuō)公元2016年)渊抄,如果你并不是在維護(hù)歷史遺留的文本處理代碼,沒(méi)有在每個(gè)地方都使用Unicod...
    縱橫而樂(lè)閱讀 2,760評(píng)論 3 16
  • 前兩天看豐子愷的書(shū)丧裁,他把左額上長(zhǎng)長(zhǎng)的疤叫做“夢(mèng)痕”护桦,說(shuō)是夢(mèng)一般的兒童時(shí)代遺留的唯一痕跡,因著這痕跡可以探尋兒...
    a若雪閱讀 439評(píng)論 1 3