1惭蹂、位:
數(shù)據(jù)存儲(chǔ)的最小單位。每個(gè)二進(jìn)制數(shù)字0或者1就是1個(gè)位割粮;
2盾碗、字節(jié):
8個(gè)位構(gòu)成一個(gè)字節(jié);即:1 byte (字節(jié))= 8 bit(位)舀瓢;
1 KB = 1024 B(字節(jié))廷雅;
1 MB = 1024 KB; (2^10 B)
1 GB = 1024 MB; (2^20 B)
1 TB = 1024 GB; (2^30 B)
3、字符:
a京髓、A航缀、中、+堰怨、*芥玉、の......均表示一個(gè)字符;
一般 utf-8 編碼下备图,一個(gè)漢字 字符 占用 3 個(gè) 字節(jié)灿巧;
一般 gbk 編碼下赶袄,一個(gè)漢字 字符 占用 2 個(gè) 字節(jié);
4抠藕、字符集:
即各種各個(gè)字符的集合饿肺,也就是說哪些漢字,字母(A盾似、b敬辣、c)和符號(hào)(空格、引號(hào)..)會(huì)被收入標(biāo)準(zhǔn)中零院;
5购岗、編碼:
規(guī)定每個(gè)“字符”分別用一個(gè)字節(jié)還是多個(gè)字節(jié)存儲(chǔ),用哪些字節(jié)來存儲(chǔ)门粪,這個(gè)規(guī)定就叫做“編碼”喊积。(其實(shí)際是對(duì)字符集中字符進(jìn)行編碼,即:每個(gè)字符用二進(jìn)制在計(jì)算中表示存儲(chǔ))玄妈;
通俗的說:編碼就是按照規(guī)則對(duì)字符進(jìn)行翻譯成對(duì)應(yīng)的二進(jìn)制數(shù)乾吻,在計(jì)算器中運(yùn)行存儲(chǔ),用戶看的時(shí)候(比如瀏覽器)拟蜻,在用對(duì)應(yīng)的編碼解析出來用戶能看懂的绎签;
(1)標(biāo)準(zhǔn)ASCii字符集:有96個(gè)打印字符,和32個(gè)控制字符組成酝锅;一共96+32=128個(gè)诡必;
用7位二進(jìn)制數(shù)來對(duì)每1個(gè)字符進(jìn)行編碼;
而由于7位還還不夠1個(gè)字節(jié)搔扁,而電腦的內(nèi)部常用字節(jié)來用處理爸舒,每個(gè)字節(jié)中多出來的最高位用0替代;
0 000 0000.........................0
0 111 1111..........................127稿蹲; 從0----127扭勉,來表示128個(gè)ACSii編碼;
比如:字符 'A'----------在計(jì)算器內(nèi)部用0100 0001 (65)來表示苛聘;
字符'a'-----------在計(jì)算器內(nèi)部用0 110 0001 (97)來表示涂炎;
注意:'10'在計(jì)算器內(nèi)部是沒有編碼的,因?yàn)樗亲址杌皇菃蝹€(gè)字符唱捣。可以分別對(duì)1,0字符編碼存儲(chǔ)网梢;
(2)擴(kuò)展ASCii字符集:將標(biāo)準(zhǔn)的ASCii最高位1震缭,得到十進(jìn)制代碼128---255(1 000 0000----1 111 1111)畅姊;所以字符集一共有0---255, 256個(gè)字符瓦哎;
(3)gb2312字符集: 所有漢字字符在計(jì)算機(jī)內(nèi)部采用2個(gè)字節(jié)來表示期丰,每個(gè)字節(jié)的最高位規(guī)定為1【正好與標(biāo)準(zhǔn)ASCii字符(最高位是0)不重疊挂捻,并兼容】活烙,不支持繁體字徐裸;
所以:gb2312表示漢字的編碼為:[129--255][129--255] (兩個(gè)字節(jié),每個(gè)字節(jié)最高位是1)啸盏;小于127的字符重贺,與ASCii編碼相同;
(4)gbk字符集:gb2312的擴(kuò)充回懦,兼容gb2312气笙,除了收錄gb2312所有的字符外,還收錄了其他不常見的漢字怯晕、繁體字等潜圃;
gbk中字符是一個(gè)或兩個(gè)字節(jié),單字節(jié)字符00--7F(0---127)這個(gè)區(qū)間和ASCII是一樣的舟茶;
雙字節(jié)字符的第一個(gè)字節(jié)是在81--FE(129--254)之間谭期。通過這個(gè)可以判斷是單字節(jié)還是雙字節(jié);
即:在gbk字符編碼吧凉,如果第一個(gè)字節(jié)是>128的隧出,則再往后找一個(gè)字節(jié),組成漢字阀捅;如果第一個(gè)字節(jié)<128,則表示的是一個(gè)單字節(jié)(此時(shí)和ASCII是一樣的)胀瞪;
<?php// gbk編碼下,無亂碼截取中文字符饲鄙; // 方法1:自定義函數(shù)1; function subgbk($str,$lens){ // 形參 $str 表示將要截取的原始字符串凄诞, $lens 表示 設(shè)定需要截取的 字符 個(gè)數(shù); if($lens<=0){ return ''; } $chars = 0; // 計(jì)算忍级,統(tǒng)計(jì)已經(jīng)截取的字符個(gè)數(shù)幔摸; $res = ''; // 已經(jīng)截取的字符長(zhǎng)度; $offset = 0; // 偏移量,從字符串中那個(gè)字節(jié)開始截取; $lengths = strlen($str); // 將要截取的原始字符串 字節(jié) 的數(shù); while($chars<$lens && $offset<$lengths){ $hight = ord(substr($str,$offset,1)); // 計(jì)算出 gbk字符中 高字節(jié)的所對(duì)應(yīng)編碼的值; if($hight>128){ // 截取兩個(gè)字節(jié)颤练,代表一個(gè)字符既忆;即:雙字節(jié)字符; $count = 2; }else{ //截取一個(gè)字節(jié),代表一個(gè)字符嗦玖,即:?jiǎn)巫止?jié)字符患雇; $count = 1; } $res .= substr($str,$offset,$count); $offset += $count; $chars++; } return $res;}?>
<?php // 方法2:自定義函數(shù)2; // 思路:先把字符串中 所有的 字符 逐一取出來 組成數(shù)組宇挫,然后對(duì) 數(shù)組元素 進(jìn)行截取;最后截取出的數(shù)組拼接成想要的字符串; function strgbk2($str,$strat,$length=NULL){ // 第三個(gè)參數(shù)默認(rèn)設(shè)置的值是NULL苛吱,這個(gè)參數(shù)是參考了下邊的array_slice()函數(shù),如果省略的話器瘪,則表示翠储,一直截取到最后末尾; $zijielen = strlen($str); // 計(jì)算出 原始字符串 $str 的 字節(jié)長(zhǎng)度; $chars = 0; // 統(tǒng)計(jì)計(jì)算截取的 字符 數(shù); $zifuarr = array(); //將字符串按照 字符 的形式 分割到 數(shù)組中绘雁;(待存儲(chǔ)); for($i = 0;$i<$zijielen;){ // $i 表示 原始字符串 $str 中的字節(jié)(標(biāo)記); if(ord(substr($str,$i,1)) > 128){ // 雙字節(jié)字符,兩個(gè)字節(jié)來表示一個(gè)字符援所; $zifuarr[] = $str[$i].$str[$i+1]; // $zifuarr[] = substr($str,$i,2); 兩種寫法的意思是一樣的,都是 取得 某個(gè)字符 某些的 字節(jié)庐舟; $i += 2; }else{ // 單字節(jié)字符,一個(gè)字節(jié)表示一個(gè)字符住拭; $zifuarr[] = $str[$i]; // $zifuarr[] = substr($str,$i,1); 兩種寫法的意思是一樣的,都是 取得 某個(gè)字符 某個(gè)的 字節(jié)挪略; $i++; } $chars++; // 每次循環(huán),相當(dāng)于截取一個(gè)存儲(chǔ) 字符; 相當(dāng)于所有的數(shù)組元素個(gè)數(shù) count($zifuarr); } if($chars < $strat){ // 當(dāng)偏移 過 字符 總長(zhǎng)度時(shí)候滔岳;(開始截取的位置杠娱,已經(jīng)超過了字符的總長(zhǎng)度); return 'No characters have been found !'; } return implode(array_slice($zifuarr,$strat,$length)); // array_slice()是截取數(shù)組一部分;implode()是將截取出來的字符串谱煤,鏈接起來摊求; } ?>
<?php // 方法3:用php內(nèi)置的函數(shù) mb_substr截取刘离; //此函數(shù)和 mb_strlen()函數(shù)一樣室叉,都是針對(duì) 多字節(jié) 字符 的操作函數(shù),在特定的編碼下寥闪,針對(duì) 字符 的 截取(mb_substr)和長(zhǎng)度的計(jì)算(mb_strlen)太惠; $strgbk = 'ds我是fdg一個(gè)中國(guó)xghdt人';echo mb_substr($strgbk,2,3,'gbk'); // 我是f ?>
(5)Unicode字符集:容納世界上所有語(yǔ)言字符和符號(hào)的集合;(以及對(duì)應(yīng)的二進(jìn)制數(shù)字)疲憋;
Unicode只是一個(gè)編碼規(guī)范凿渊,目前實(shí)際實(shí)現(xiàn)的unicode編碼只要有三種:UTF-8,UCS-2和UTF-16,三種unicode字符集之間可以按照規(guī)范進(jìn)行轉(zhuǎn)換缚柳。
(6)utf-8編碼:UTF-8(8-bit Unicode Transformation Format)是一種針對(duì)Unicode的可變長(zhǎng)度字符編碼埃脏,也是一種前綴碼。它可以用來表示Unicode標(biāo)準(zhǔn)中的任何字符秋忙,且其編碼中的第一個(gè)字節(jié)仍與ASCII兼容彩掐,這使得原來處理ASCII字符的軟件無須或只須做少部分修改,即可繼續(xù)使用灰追。因此堵幽,它逐漸成為電子郵件、網(wǎng)頁(yè)及其他存儲(chǔ)或發(fā)送文字的應(yīng)用中弹澎,優(yōu)先采用的編碼朴下。
[圖片上傳失敗...(image-336de6-1532481532441)]
對(duì)于UTF-8編碼中的任意字節(jié)B,如果B的第一位為0苦蒿,則B獨(dú)立的表示一個(gè)字符(ASCII碼)殴胧;
如果B的第一位為1,第二位為0,則B為一個(gè)多字節(jié)字符中的一個(gè)字節(jié)(非ASCII字符)团滥;
如果B的前兩位為1竿屹,第三位為0,則B為兩個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié)灸姊;
如果B的前三位為1拱燃,第四位為0,則B為三個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié)厨钻;
如果B的前四位為1扼雏,第五位為0坚嗜,則B為四個(gè)字節(jié)表示的字符中的第一個(gè)字節(jié)夯膀;
因此,對(duì)UTF-8編碼中的任意字節(jié)苍蔬,根據(jù)第一位诱建,可判斷是否為ASCII字符;根據(jù)前二位碟绑,可判斷該字節(jié)是否為一個(gè)字符編碼的第一個(gè)字節(jié)俺猿;根據(jù)前四位(如果前兩位均為1),可確定該字節(jié)為字符編碼的第一個(gè)字節(jié)格仲,并且可判斷對(duì)應(yīng)的字符由幾個(gè)字節(jié)表示押袍;根據(jù)前五位(如果前四位為1),可判斷編碼是否有錯(cuò)誤或數(shù)據(jù)傳輸過程中是否有錯(cuò)誤凯肋。
即:
1谊惭、單字節(jié)的字符,字節(jié)的第一位設(shè)為0侮东,對(duì)于英語(yǔ)文本圈盔,UTF-8碼只占用一個(gè)字節(jié),和ASCII碼完全相同悄雅;
2驱敲、n個(gè)字節(jié)的字符(n>1),第一字節(jié)的前n位設(shè)為1宽闲,第n+1位設(shè)為0众眨,后面字節(jié)的前兩位都設(shè)為10;
3容诬、2個(gè)字節(jié)娩梨,第一個(gè)字節(jié)的前2位是1;3個(gè)字節(jié)放案,第一個(gè)字節(jié)的前三位是1姚建; 4個(gè)字節(jié),第一個(gè)字節(jié)的前4位都是1吱殉;
// 如何截取中文掸冤,無亂碼厘托,假設(shè)utf-8編碼;
<?php // 方法1:自定義函數(shù)稿湿; function subutf8($str,$len){ // 兩個(gè)形式參數(shù)铅匹,$str代表原始目標(biāo)字符串,$len表示需要截取 字符 的個(gè)數(shù); 注意是 字符的 個(gè)數(shù)饺藤; if($len<=0){ // 當(dāng) 將要截取的字符數(shù) <=0的時(shí)候 返回 空字符串包斑; return ''; } $chars = 0 ; // $chars 參數(shù) 代表 已經(jīng)截取的字符的個(gè)數(shù), 默認(rèn)初始設(shè)置為0涕俗; $res = ''; // $res 參數(shù) 表示 已經(jīng)截取的字符串的長(zhǎng)度罗丰, 默認(rèn)初始設(shè)置為空(字符串); $offset = 0; // $offset 參數(shù) 表示 字節(jié) 截取的偏移量; 即從字符串中(偏移幾個(gè)字節(jié))哪個(gè)字節(jié)開始截仍俟谩萌抵; $lengths = strlen($str); // $lengths 參數(shù) 表示 原始整個(gè)字符串的 字節(jié)的長(zhǎng)度; 而應(yīng)保證 $offset < $lengths; 否則都無字符可截取元镀; while($chars<$len && $offset < $lengths){ // $chars<$len; 應(yīng)是< 而不是<= 绍填;因?yàn)槭菑?開始的,并執(zhí)行循環(huán)截取的栖疑; $higher = decbin(ord(substr($str,$offset,1))); // 計(jì)算出 一個(gè)字符 中 第一個(gè)字節(jié)(高字節(jié))的二進(jìn)制讨永; if(strlen($higher) < 8){ // decbin()函數(shù) 轉(zhuǎn)換出來的 二進(jìn)制數(shù) 如果 <128(10000000) 的時(shí)候,即是二進(jìn)制長(zhǎng)度<8位的時(shí)候遇革,前面高位不默認(rèn)補(bǔ)0卿闹; // 截取一個(gè)字節(jié);(表示一個(gè)字符)澳淑; $count = 1; }else if(substr($higher,0,3) == '110'){ //截取兩個(gè)字節(jié)(表示一個(gè)字符)比原; $count = 2; }else if(substr($higher,0,4) == '1110'){ //截取三個(gè)字節(jié)(表示一個(gè)字符); $count = 3; }else if(substr($higher,0,5) == '11110'){ //截取四個(gè)字節(jié)(表示一個(gè)字符)杠巡; $count = 4; }else if(substr($higher,0,6) == '111110'){ //截取五個(gè)字節(jié)(表示一個(gè)字符)量窘; $count = 5; }else if(substr($higher,0,7) == '1111110'){ //截取六個(gè)字節(jié)(表示一個(gè)字符); $count = 6; } $res .= substr($str,$offset,$count); $offset += $count; $chars++; } return $res;} ?>
<?php //方法2:使用系統(tǒng)函數(shù)截取mb_substr(),不會(huì)亂碼.例:$str = '換s幾ss個(gè)字實(shí)現(xiàn)中文字串截取無亂碼的方法氢拥。';echo mb_substr($str,0,5,'UTF-8');// '換s幾ss' ?>php
// 中文字符串實(shí)現(xiàn)反轉(zhuǎn); $a = '我是一個(gè)好人';function strrevv($str) { $strlen = mb_strlen($str,'UTF-8'); $arr = array(); for($a=0;$a<=$strlen;$a++) { $arr[] = mb_substr($str,$a,1,'UTF-8'); } $newstr = implode('',array_reverse($arr)); return $newstr;}echo strrevv($a); // mb_strlen(str,utf-8); 字符串中字符的個(gè)數(shù); // mb_substr(str,start,length,utf-8); 多字節(jié)字符的截取; // mb_strpos(str,needle,offset,utf-8);查找子字符串蚌铜,在字符串中出現(xiàn)的位置; // mb_substr_count(str,needle,utf-8);統(tǒng)計(jì)子字符串,在字符串中出現(xiàn)的次數(shù);