javascript - 在 JavaScript 中计算以 ISO 8859-7 编码的文件的字节大小

标签 javascript encoding character-encoding

背景

我正在编写一种名为 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 字符,你可能需要做以下两件事之一:

  1. 计算该程序的字节数,即 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;
}
  1. 创建您自己的 ISO-8859-7 自定义变体,它使用特定字节(或多个字节)来表示接下来的 2 或 3 个字节属于单个 Unicode 字符。这可以根据您的喜好简单或复杂,从一个表示 2 字节字符的字符和一个表示 3 字节字符到 809F 设置之间的所有内容为接下来的几个。这是一个使用 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/

相关文章:

java - 为什么 Windows 在 java 中的 system.out.print 上显示问号?

c# - Linux 上 .NET Core 的字符编码错误

javascript - 如何在 Javascript ES6 中按年和月排序

javascript - 为什么要使用 Promise.catch() 而不是 Promise.then()

java - 如何修复 maven 中俄语编码的错误?

Python googletrans编码奇怪的字符

php - 语言翻译不正确(例如阿拉伯语)

javascript - 将父级添加到多个 <li> 标签

javascript - 正则表达式先行

c++ - 将 Matlab 生成的二进制字符串转换为 float