js實現(xiàn)unicode碼字符串與utf8字節(jié)數(shù)據(jù)互轉詳解
js的string變量存儲字符串使用的是unicode編碼,要保存時必須選擇其他編碼后進行傳輸,比如轉成utf-8,utf-32等。存儲到數(shù)據(jù)庫中為utf-8編碼,讀取出來如何轉換成正確的字符串就成了問題?,F(xiàn)在給出解決方案,可以正確支持中文、emoji表情、英文混合的字符串編碼互轉。
/**
* Created by hdwang on 2019/1/28.
*/
var convertUtf8 = (function() {
/**
* unicode string to utf-8
* @param text 字符串
* @returns {*} utf-8編碼
*/
function toBytes(text) {
var result = [], i = 0;
text = encodeURI(text);
while (i < text.length) {
var c = text.charCodeAt(i++);
// if it is a % sign, encode the following 2 bytes as a hex value
if (c === 37) {
result.push(parseInt(text.substr(i, 2), 16))
i += 2;
// otherwise, just the actual byte
} else {
result.push(c)
}
}
return coerceArray(result);
}
/**
* utf8 byte to unicode string
* @param utf8Bytes
* @returns {string}
*/
function utf8ByteToUnicodeStr(utf8Bytes){
var unicodeStr ="";
for (var pos = 0; pos < utf8Bytes.length;){
var flag= utf8Bytes[pos];
var unicode = 0 ;
if ((flag >>>7) === 0 ) {
unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
pos += 1;
} else if ((flag &0xFC) === 0xFC ){
unicode = (utf8Bytes[pos] & 0x3) << 30;
unicode |= (utf8Bytes[pos+1] & 0x3F) << 24;
unicode |= (utf8Bytes[pos+2] & 0x3F) << 18;
unicode |= (utf8Bytes[pos+3] & 0x3F) << 12;
unicode |= (utf8Bytes[pos+4] & 0x3F) << 6;
unicode |= (utf8Bytes[pos+5] & 0x3F);
unicodeStr+= String.fromCodePoint(unicode) ;
pos += 6;
}else if ((flag &0xF8) === 0xF8 ){
unicode = (utf8Bytes[pos] & 0x7) << 24;
unicode |= (utf8Bytes[pos+1] & 0x3F) << 18;
unicode |= (utf8Bytes[pos+2] & 0x3F) << 12;
unicode |= (utf8Bytes[pos+3] & 0x3F) << 6;
unicode |= (utf8Bytes[pos+4] & 0x3F);
unicodeStr+= String.fromCodePoint(unicode) ;
pos += 5;
} else if ((flag &0xF0) === 0xF0 ){
unicode = (utf8Bytes[pos] & 0xF) << 18;
unicode |= (utf8Bytes[pos+1] & 0x3F) << 12;
unicode |= (utf8Bytes[pos+2] & 0x3F) << 6;
unicode |= (utf8Bytes[pos+3] & 0x3F);
unicodeStr+= String.fromCodePoint(unicode) ;
pos += 4;
} else if ((flag &0xE0) === 0xE0 ){
unicode = (utf8Bytes[pos] & 0x1F) << 12;;
unicode |= (utf8Bytes[pos+1] & 0x3F) << 6;
unicode |= (utf8Bytes[pos+2] & 0x3F);
unicodeStr+= String.fromCharCode(unicode) ;
pos += 3;
} else if ((flag &0xC0) === 0xC0 ){ //110
unicode = (utf8Bytes[pos] & 0x3F) << 6;
unicode |= (utf8Bytes[pos+1] & 0x3F);
unicodeStr+= String.fromCharCode(unicode) ;
pos += 2;
} else{
unicodeStr+= String.fromCharCode(utf8Bytes[pos]);
pos += 1;
}
}
return unicodeStr;
}
function checkInt(value) {
return (parseInt(value) === value);
}
function checkInts(arrayish) {
if (!checkInt(arrayish.length)) { return false; }
for (var i = 0; i < arrayish.length; i++) {
if (!checkInt(arrayish[i]) || arrayish[i] < 0 || arrayish[i] > 255) {
return false;
}
}
return true;
}
function coerceArray(arg, copy) {
// ArrayBuffer view
if (arg.buffer && arg.name === 'Uint8Array') {
if (copy) {
if (arg.slice) {
arg = arg.slice();
} else {
arg = Array.prototype.slice.call(arg);
}
}
return arg;
}
// It's an array; check it is a valid representation of a byte
if (Array.isArray(arg)) {
if (!checkInts(arg)) {
throw new Error('Array contains invalid value: ' + arg);
}
return new Uint8Array(arg);
}
// Something else, but behaves like an array (maybe a Buffer? Arguments?)
if (checkInt(arg.length) && checkInts(arg)) {
return new Uint8Array(arg);
}
throw new Error('unsupported array-like object');
}
return {
toBytes: toBytes,
fromBytes: utf8ByteToUnicodeStr
}
})()
針對emoji的字節(jié)字符,占兩個unicode字符。使用String.fromCharCode也可以實現(xiàn),需要進行兩次fromCharCode,沒有fromPointCode方便。下面展示了utf-8的4字節(jié)轉換為unicode(utf-16)的過程。
//高char10位[一個unicode字符] (2+6+2=10)
unicode = ((utf8Bytes[pos] & 0x3)) << 8 |((utf8Bytes[pos+1] & 0x3f) << 2) |((utf8Bytes[pos+2] >> 4) & 0x03);
//減去1F600中的1,這里減去6個0即可,低位char已經(jīng)占據(jù)10位
unicode = unicode - parseInt('1000000',2)
//加上utf-16高char的標識符
unicode = 0xD800 + unicode;
console.log(unicode);
unicodeStr += String.fromCharCode(unicode);
//低char10位[一個unicode字符](4+6)
unicode = ((utf8Bytes[pos+2] & 0x0F) << 6) | (utf8Bytes[pos+3] & 0x3F);
//加上utf-16低char的標識符
unicode = 0xDC00 + unicode;
console.log(unicode);
unicodeStr+= String.fromCharCode(unicode);
pos += 4;
以上所述是小編給大家介紹的js實現(xiàn)unicode碼字符串與utf8字節(jié)數(shù)據(jù)互轉詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關文章
Javascript的IE和Firefox兼容性匯編(zz)
[紅色]Javascript的IE和Firefox兼容性匯編(zz)...2007-02-02
關于JavaScript的URL.createObjectURL()的使用方法
這篇文章主要介紹了關于URL.createObjectURL()的使用方法,使用createObjectURL可以節(jié)省性能并更快速,只不過需要在不使用的情況下手動釋放內(nèi)存,還不清楚的朋友一起來看看吧2023-04-04
javascript 全選與全取消功能的實現(xiàn)代碼
全選與全取消在工作過程中經(jīng)常會使用到,是因為它很方便,同時可以提高用戶體驗值,本文介紹如何使用javascript實現(xiàn)全選與全取消功能,需要了解的朋友可以參考下2012-12-12
JavaScript 基本數(shù)據(jù)類型轉換你了解嘛
這篇文章主要為大家介紹了JavaScript基本數(shù)據(jù)類型轉換,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助2022-01-01

