背景
我正在编写一种名为 Jolf 的深奥语言.它用于可爱的网站codegolf SE .如果您还不知道,很多挑战都是以字节计分的。人有made lots of languages使用他们自己的编码或预先存在的编码。
在我的语言的解释器上,我有一个字节计数器。如您所料,它计算代码中的字节数。到目前为止,我一直在使用 UTF-8 en/decoder ( utf8.js
)。我现在使用的是 ISO 8859-7 编码,其中包含希腊字符。文本上传实际上也不起作用。我需要计算上传文件中包含的实际字节数。另外,有没有办法读取所述编码文件的内容?
问题
给定一个以 ISO 8859-7 编码的文件,该文件来自 <input>
页面上的元素,有没有办法获得该文件中包含的字节数?并且,给定“纯文本”(即直接放入 <textarea>
的文本),我如何计算其中的字节数,就好像它是用 ISO 8859-7 编码的一样?
我尝试过的
输入元素称为isogreek
.该文件位于 <input>
元素。内容是ΦX族
,一个希腊字符,一个拉丁字符(每一个都应该是一个字节)和一个汉字,应该多于一个字节(?)。
isogreek.files[0].size; // is 3; should be more.
var reader = new FileReader();
reader.readAsBinaryString(isogreek.files[0]); // corrupts the string to `ÖX?`
reader.readAsText(isogreek.files[0]); // �X?
reader.readAsText(isogreek.files[0],"ISO 8859-7"); // �X?
最佳答案
扩展自 this comment .
正如@pvg 在评论中提到的,readAsBinaryString
产生的字符串是正确的,但由于两个原因而损坏了:
一个。结果以 ISO-8859-1 编码。您可以使用一个函数来解决这个问题:
function convertFrom1to7(text) {
// charset is the set of chars in the ISO-8859-7 encoding from 0xA0 and up, encoded with this format:
// - If the character is in the same position as in ISO-8859-1/Unicode, use a "!".
// - If the character is a Greek char with 720 subtracted from its char code, use a ".".
// - Otherwise, use \uXXXX format.
var charset = "!\u2018\u2019!\u20AC\u20AF!!!!.!!!!\u2015!!!!...!...!.!....................!............................................!";
var newtext = "", newchar = "";
for (var i = 0; i < text.length; i++) {
var char = text[i];
newchar = char;
if (char.charCodeAt(0) >= 160) {
newchar = charset[char.charCodeAt(0) - 160];
if (newchar === "!") newchar = char;
if (newchar === ".") newchar = String.fromCharCode(char.charCodeAt(0) + 720);
}
newtext += newchar;
}
return newtext;
}
B.汉字不是 ISO-8859-7 charset 的一部分(因为字符集最多支持 256 个唯一字符,如表所示)。如果你想在程序中包含任意 Unicode 字符,你可能需要做以下两件事之一:
- 计算该程序的字节数,即 UTF-8 或 UTF-16。使用您链接的库可以很容易地完成此操作。但是,如果您希望自动完成此操作,则需要一个函数来检查文本区域的内容是否是有效的 ISO-8859-7 文件,如下所示:
function isValidISO_8859_7(text) {
var charset = /[\u0000-\u00A0\u2018\u2019\u00A3\u20AC\u20AF\u00A6-\u00A9\u037A\u00AB-\u00AD\u2015\u00B0-\u00B3\u0384-\u0386\u00B7\u0388-\u038A\u00BB\u038C\u00BD\u038E-\u03CE]/;
var valid = true;
for (var i = 0; i < text.length; i++) {
valid = valid && charset.test(text[i]);
}
return valid;
}
- 创建您自己的 ISO-8859-7 自定义变体,它使用特定字节(或多个字节)来表示接下来的 2 或 3 个字节属于单个 Unicode 字符。这可以根据您的喜好简单或复杂,从一个表示 2 字节字符的字符和一个表示 3 字节字符到
80
和9F
设置之间的所有内容为接下来的几个。这是一个使用80
作为 2 字节和81
作为 3 字节的基本示例(假设文本以 ISO-8859-1 编码):
function reUnicode(text) {
var newtext = "";
for (var i = 0; i < text.length; i++) {
if (text.charCodeAt(i) === 0x80) {
newtext += String.fromCharCode((text.charCodeAt(++i) << 8) + text.charCodeAt(++i));
} else if (text.charCodeAt(i) === 0x81) {
var charcode = (text.charCodeAt(++i) << 16) + (text.charCodeAt(++i) << 8) + text.charCodeAt(++i) - 65536;
newtext += String.fromCharCode(0xD800 + (charcode >> 10), 0xDC00 + (charcode & 1023)); // Convert into a UTF-16 surrogate pair
} else {
newtext += convertFrom1to7(text[i]);
}
}
return newtext;
}
如果您愿意,我可以更详细地介绍这两种方法。
关于javascript - 在 JavaScript 中计算以 ISO 8859-7 编码的文件的字节大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34779256/