如何在JavaScript中将文本转换为二进制代码?

75

我希望JavaScript能够将文本区域中的文字翻译成二进制代码。

例如,如果用户在文本区域中输入“TEST”,则应该返回值“01010100 01000101 01010011 01010100”。

我想避免使用switch语句为每个字符赋一个二进制代码值(例如case "T": return "01010100)或任何其他类似的技术。

这里是一个JSFiddle演示我所说的。在本机JavaScript中是否有可能实现?


1
通过谷歌找到了这个。我认为这就是你要找的东西。http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/Binary_To_Text.asp - Charles
在 JavaScript 中,您可以使用 charCodeAt 方法来获取字符串的字符编码。 - mpm
1
人们应该意识到,在JavaScript中,字符串以UTF-16的形式存储。因此,您将拥有UTF-16二进制表示。如果您想要其他格式,例如UTF-8,则必须在编码为二进制之前手动将charcodes转换为UTF-8(示例在这里)。 - Buzut
20个回答

76

你应该使用 charCodeAt 函数将每个字符转换为 Ascii 十进制编码,然后可以使用 toString(2) 将其转换为二进制值:

function convert() {
  var output = document.getElementById("ti2");
  var input = document.getElementById("ti1").value;
  output.value = "";
  for (var i = 0; i < input.length; i++) {
      output.value += input[i].charCodeAt(0).toString(2) + " ";
  }
}
<input id="ti1" value ="TEST"/>
<input id="ti2"/>
<button onClick="convert();">Convert!</button>

这里有一个 JSFiddle:http://jsfiddle.net/fA24Y/1/


2
左侧填充的另一种方法:var a = 'a'.charCodeAt(0).toString(2); /* a == "1100001" */ a = new Array(9 - a.length).join('0') + a; /* a == "01100001" */. - user1636522
1
问题:难道没有其他方法可以做到这一点,比如用这个文本创建一个 blob,然后使用 filereader 将其输出为二进制数据……但是对我来说似乎只输出了文本。 - Muhammad Umer
2
未来的读者请注意:字符集不仅限于8位。请尝试使用charToBin("")函数。 - Matthew.Lothian
3
为什么不使用"input.charCodeAt(i)"呢? - tedebus
3
这段代码存在前导零的问题。 output.value += (0b100000000 + input[i].charCodeAt(0)).toString(2).substring(1) + " "; 可以解决该问题。 - Kyle Berezin
显示剩余2条评论

49

这可能是您能得到的最简单的:

function text2Binary(string) {
    return string.split('').map(function (char) {
        return char.charCodeAt(0).toString(2);
    }).join(' ');
}

1
+1 给 "join" 函数,修复被接受答案的尾随空格。你也可以添加 .padStart(8,'0') 来强制每个字符都占据 8 位。 - Random

12
  1. 遍历字符串
  2. 将每个字符转换为它们的字符编码
  3. 将字符编码转换为二进制
  4. 将其推入数组并添加左侧的0
  5. 返回由空格分隔的字符串

代码:

function textToBin(text) {
  var length = text.length,
      output = [];
  for (var i = 0;i < length; i++) {
    var bin = text[i].charCodeAt().toString(2);
    output.push(Array(8-bin.length+1).join("0") + bin);
  } 
  return output.join(" ");
}
textToBin("!a") => "00100001 01100001"

另一种方式

function textToBin(text) {
  return (
    Array
      .from(text)
      .reduce((acc, char) => acc.concat(char.charCodeAt().toString(2)), [])
      .map(bin => '0'.repeat(8 - bin.length) + bin )
      .join(' ')
  );
}

1
你可以通过将 8 改为 9 来省略 9-bin.length+1 中的 +1,像这样:function textToBin(text) { var length = text.length, output = []; for (var i = 0;i < length; i++) { var bin = text[i].charCodeAt().toString(2); output.push(Array(9-bin.length).join("0") + bin); } return output.join(" "); } - Subtubes
更简单的方法是 output.push(('0000000' + bin).slice(-8))。;-) 但是有些字符,比如 endash,超过了8位:charCode 8212 -> 10000000010100。 - RobG

8

这里是我之前写的一个非常通用的本地实现,具体内容可以参考这个链接

// ABC - a generic, native JS (A)scii(B)inary(C)onverter.
// (c) 2013 Stephan Schmitz <eyecatchup@gmail.com>
// License: MIT, http://eyecatchup.mit-license.org
// URL: https://gist.github.com/eyecatchup/6742657
var ABC = {
  toAscii: function(bin) {
    return bin.replace(/\s*[01]{8}\s*/g, function(bin) {
      return String.fromCharCode(parseInt(bin, 2))
    })
  },
  toBinary: function(str, spaceSeparatedOctets) {
    return str.replace(/[\s\S]/g, function(str) {
      str = ABC.zeroPad(str.charCodeAt().toString(2));
      return !1 == spaceSeparatedOctets ? str : str + " "
    })
  },
  zeroPad: function(num) {
    return "00000000".slice(String(num).length) + num
  }
};

并按如下方式使用:
var binary1      = "01100110011001010110010101101100011010010110111001100111001000000110110001110101011000110110101101111001",
    binary2      = "01100110 01100101 01100101 01101100 01101001 01101110 01100111 00100000 01101100 01110101 01100011 01101011 01111001",
    binary1Ascii = ABC.toAscii(binary1),
    binary2Ascii = ABC.toAscii(binary2);

console.log("Binary 1:                   " + binary1);
console.log("Binary 1 to ASCII:          " + binary1Ascii);
console.log("Binary 2:                   " + binary2);
console.log("Binary 2 to ASCII:          " + binary2Ascii);
console.log("Ascii to Binary:            " + ABC.toBinary(binary1Ascii));     // default: space-separated octets
console.log("Ascii to Binary /wo spaces: " + ABC.toBinary(binary1Ascii, 0));  // 2nd parameter false to not space-separate octets

源代码在Github上(gist):https://gist.github.com/eyecatchup/6742657

希望能对您有所帮助。可以自由使用,但需要遵守MIT许可证规定。


7
var PADDING = "00000000"

var string = "TEST"
var resultArray = []

for (var i = 0; i < string.length; i++) {
  var compact = string.charCodeAt(i).toString(2)
  var padded  = compact.substring(0, PADDING.length - compact.length) + compact

  resultArray.push(padded)
}

console.log(resultArray.join(" "))

你的代码有问题,我在这里检查了结果- http://www.binaryhexconverter.com/ascii-text-to-binary-converter、http://www.roubaixinteractive.com/PlayGround/Binary_Conversion/Binary_To_Text.asp 和 http://string-functions.com/string-binary.aspx你的代码总是在第一个数字处放置“1”。 - Kasmetski
@Kasmetski 这是正确的,你需要下面这段代码才能使它工作:var padded = PADDING.substring(0, PADDING.length - compact.length) + compact - Ferry Kobus

6

其他答案对于大多数情况都适用。但值得注意的是,charCodeAt()及相关函数不适用于UTF-8字符串(也就是说,如果存在任何标准ASCII范围之外的字符,它们会抛出错误)。以下是一种解决方法。

// UTF-8 to binary
var utf8ToBin = function( s ){
    s = unescape( encodeURIComponent( s ) );
    var chr, i = 0, l = s.length, out = '';
    for( ; i < l; i ++ ){
        chr = s.charCodeAt( i ).toString( 2 );
        while( chr.length % 8 != 0 ){ chr = '0' + chr; }
        out += chr;
    }
    return out;
};

// Binary to UTF-8
var binToUtf8 = function( s ){
    var i = 0, l = s.length, chr, out = '';
    for( ; i < l; i += 8 ){
        chr = parseInt( s.substr( i, 8 ), 2 ).toString( 16 );
        out += '%' + ( ( chr.length % 2 == 0 ) ? chr : '0' + chr );
    }
    return decodeURIComponent( out );
};

escape/unescape() 函数已被弃用。如果你需要它们的 polyfills,可以查看这里更全面的 UTF-8 编码示例:http://jsfiddle.net/47zwb41o


5

前导0的8位字符

'sometext'
        .split('')
        .map((char) => '00'.concat(char.charCodeAt(0).toString(2)).slice(-8))
        .join(' ');

如果你需要6或7位,只需更改 .slice(-8)


5

只是一个指向正确方向的提示。

var foo = "TEST",
    res = [ ];

foo.split('').forEach(function( letter ) {
    var bin     = letter.charCodeAt( 0 ).toString( 2 ),
        padding = 8 - bin.length;

    res.push( new Array( padding+1 ).join( '0' ) + bin );
});

console.log( res );

5

感谢Majid Laissi提供的答案

我从您的代码中创建了2个函数:

目标是实现字符串到VARBINARY、BINARY的转换以及相反的转换。

const stringToBinary = function(string, maxBytes) {
  //for BINARY maxBytes = 255
  //for VARBINARY maxBytes = 65535
  let binaryOutput = '';
  if (string.length > maxBytes) {
    string = string.substring(0, maxBytes);
  }

  for (var i = 0; i < string.length; i++) {
    binaryOutput += string[i].charCodeAt(0).toString(2) + ' ';
  }

  return binaryOutput;
};

以及反向转换:

const binaryToString = function(binary) {
  const arrayOfBytes = binary.split(' ');

  let stringOutput = '';

  for (let i = 0; i < arrayOfBytes.length; i++) {
    stringOutput += String.fromCharCode(parseInt(arrayOfBytes[i], 2));
  }

  return stringOutput;
};

以下是一个可用的示例:https://jsbin.com/futalidenu/edit?js,console


4

假设您在 Node 或支持 BigInt 的浏览器中工作,此版本通过仅在最后保存昂贵的字符串构造来降低成本:

const zero = 0n
const shift = 8n

function asciiToBinary (str) {
  const len = str.length
  let n = zero
  for (let i = 0; i < len; i++) {
    n = (n << shift) + BigInt(str.charCodeAt(i))
  }
  return n.toString(2).padStart(len * 8, 0)
}

它的速度大约是其他提到的解决方案(包括这个简单的ES6+实现)的两倍。

const toBinary = s => [...s]
  .map(x => x
    .codePointAt()
    .toString(2)
    .padStart(8,0)
  )
  .join('')

如果你需要处理Unicode字符,这里有一个工具可以帮助你完成:
const zero = 0n
const shift = 8n
const bigShift = 16n
const byte = 255n

function unicodeToBinary (str) {
  const len = str.length
  let n = zero
  for (let i = 0; i < len; i++) {
    const bits = BigInt(str.codePointAt(i))
    n = (n << (bits > byte ? bigShift : shift)) + bits
  }
  const bin = n.toString(2)
  return bin.padStart(8 * Math.ceil(bin.length / 8), 0)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接