Un projet récent nécessite d'utiliser js pour calculer la mémoire occupée par une chaîne écrite dans localStorage. Comme nous le savons tous, js utilise le codage Unicode. Il existe N types d'implémentations Unicode, parmi lesquelles UTF-8 et UTF-16 sont les plus couramment utilisés. Par conséquent, cet article ne traite que de ces deux codages.
La définition suivante est tirée de Wikipédia (http://zh.wikipedia.org/zh-cn/UTF-8), avec quelques suppressions.
UTF-8 (8-bit Unicode Transformation Format) est un codage de caractères de longueur variable pour Unicode qui peut représenter n'importe quel caractère de la norme Unicode, et le premier octet de son codage est toujours compatible avec ASCII, en utilisant un à quatre octets pour coder chaque caractère
Les règles d'encodage sont les suivantes :
Les codes de caractères compris entre 000000 et 00007F sont codés avec un octet
Les caractères compris entre 000080 et 0007FF utilisent deux octets ;
Utilisez trois octets entre 000800 – 00D7FF et 00E000 – 00FFFF Remarque : Unicode n'a aucun caractère dans la plage
;
Utilisez 4 octets entre 010000 et 10FFFF.
UTF-16 est un codage de caractères de longueur fixe. La plupart des caractères utilisent deux octets pour encoder, et les codes de caractères dépassant 65 535 utilisent quatre octets, comme suit :
000000 – 00FFFF deux octets
010000 – 10FFFF quatre octets.
Au début, je pensais que puisque la page est encodée en UTF-8, les chaînes stockées dans localStorage devraient également être encodées en UTF-8. Mais des tests ultérieurs ont révélé que la taille calculée était inférieure à 5 Mo, mais une exception a été levée lors de son enregistrement sur localStorage. Après réflexion, l'encodage de la page peut être modifié. Si localStorage stocke les chaînes en fonction de l'encodage de la page, ne serait-ce pas un gâchis ? Les navigateurs doivent tous utiliser le codage UTF-16. La chaîne de 5 Mo a été calculée à l’aide du codage UTF-16 et a été écrite avec succès. S’il dépasse, il échoue.
D'accord, voici l'implémentation du code. Les règles de calcul sont telles qu'écrites ci-dessus. Pour la vitesse de calcul, les deux boucles for sont écrites séparément.
/** * 计算字符串所占的内存字节数,默认使用UTF-8的编码方式计算,也可制定为UTF-16 * UTF-8 是一种可变长度的 Unicode 编码格式,使用一至四个字节为每个字符编码 * * 000000 - 00007F(128个代码) 0zzzzzzz(00-7F) 一个字节 * 000080 - 0007FF(1920个代码) 110yyyyy(C0-DF) 10zzzzzz(80-BF) 两个字节 * 000800 - 00D7FF 00E000 - 00FFFF(61440个代码) 1110xxxx(E0-EF) 10yyyyyy 10zzzzzz 三个字节 * 010000 - 10FFFF(1048576个代码) 11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz 四个字节 * * 注: Unicode在范围 D800-DFFF 中不存在任何字符 * {@link http://zh.wikipedia.org/wiki/UTF-8} * * UTF-16 大部分使用两个字节编码,编码超出 65535 的使用四个字节 * 000000 - 00FFFF 两个字节 * 010000 - 10FFFF 四个字节 * * {@link http://zh.wikipedia.org/wiki/UTF-16} * @param {String} str * @param {String} charset utf-8, utf-16 * @return {Number} */ var sizeof = function(str, charset){ var total = 0, charCode, i, len; charset = charset ? charset.toLowerCase() : ''; if(charset === 'utf-16' || charset === 'utf16'){ for(i = 0, len = str.length; i < len; i++){ charCode = str.charCodeAt(i); if(charCode <= 0xffff){ total += 2; }else{ total += 4; } } }else{ for(i = 0, len = str.length; i < len; i++){ charCode = str.charCodeAt(i); if(charCode <= 0x007f) { total += 1; }else if(charCode <= 0x07ff){ total += 2; }else if(charCode <= 0xffff){ total += 3; }else{ total += 4; } } } return total; }