[英]How to get binary string from ArrayBuffer?
從JavaScript中的ArrayBuffer獲取二進制字符串的方法是什么?
我不想對字節進行編碼,只是將二進制表示形式作為字符串。
提前致謝!
以下代碼將始終將ArrayBuffer
轉換為String
並再次返回,而不會丟失或添加任何額外字節。
function ArrayBufferToString(buffer) {
return BinaryToString(String.fromCharCode.apply(null, Array.prototype.slice.apply(new Uint8Array(buffer))));
}
function StringToArrayBuffer(string) {
return StringToUint8Array(string).buffer;
}
function BinaryToString(binary) {
var error;
try {
return decodeURIComponent(escape(binary));
} catch (_error) {
error = _error;
if (error instanceof URIError) {
return binary;
} else {
throw error;
}
}
}
function StringToBinary(string) {
var chars, code, i, isUCS2, len, _i;
len = string.length;
chars = [];
isUCS2 = false;
for (i = _i = 0; 0 <= len ? _i < len : _i > len; i = 0 <= len ? ++_i : --_i) {
code = String.prototype.charCodeAt.call(string, i);
if (code > 255) {
isUCS2 = true;
chars = null;
break;
} else {
chars.push(code);
}
}
if (isUCS2 === true) {
return unescape(encodeURIComponent(string));
} else {
return String.fromCharCode.apply(null, Array.prototype.slice.apply(chars));
}
}
function StringToUint8Array(string) {
var binary, binLen, buffer, chars, i, _i;
binary = StringToBinary(string);
binLen = binary.length;
buffer = new ArrayBuffer(binLen);
chars = new Uint8Array(buffer);
for (i = _i = 0; 0 <= binLen ? _i < binLen : _i > binLen; i = 0 <= binLen ? ++_i : --_i) {
chars[i] = String.prototype.charCodeAt.call(binary, i);
}
return chars;
}
我通過在這個 jsfiddle 中來回傳遞以下值來測試它: http : //jsfiddle.net/potatosalad/jrdLV/
(String) "abc" -> (ArrayBuffer) -> (String) "abc"
(String) "aΩc" -> (ArrayBuffer) -> (String) "aΩc"
(Uint8Array) [0,1,255] -> (ArrayBuffer) -> (String) -> (Uint8Array) [0,1,255]
(Uint16Array) [0,1,256,65535] -> (ArrayBuffer) -> (String) -> (Uint16Array) [0,1,256,65535]
(Uint32Array) [0,1,256,65536,4294967295] -> (ArrayBuffer) -> (String) -> (Uint32Array) [0,1,256,65536,4294967295]
近年來,通過對 JavaScript 的添加,這變得更加簡單——這是將 Uint8Array 轉換為二進制編碼字符串的單行方法:
const toBinString = (bytes) =>
bytes.reduce((str, byte) => str + byte.toString(2).padStart(8, '0'), '');
例子:
console.log(toBinString(Uint8Array.from([42, 100, 255, 0])))
// => '00101010011001001111111100000000'
如果您從 ArrayBuffer 開始,請創建緩沖區的 Uint8Array“視圖”以傳遞給此方法:
const view = new Uint8Array(myArrayBuffer);
console.log(toBinString(view));
來源: Libauth庫( binToBinString 方法)
這將為您提供來自類型化數組的二進制字符串
var bitsPerByte = 8;
var array = new Uint8Array([0, 50, 100, 170, 200, 255]);
var string = "";
function repeat(str, num) {
if (str.length === 0 || num <= 1) {
if (num === 1) {
return str;
}
return '';
}
var result = '',
pattern = str;
while (num > 0) {
if (num & 1) {
result += pattern;
}
num >>= 1;
pattern += pattern;
}
return result;
}
function lpad(obj, str, num) {
return repeat(str, num - obj.length) + obj;
}
Array.prototype.forEach.call(array, function (element) {
string += lpad(element.toString(2), "0", bitsPerByte);
});
console.log(string);
輸出是
000000000011001001100100101010101100100011111111
或者也許你在問這個?
function ab2str(buf) {
return String.fromCharCode.apply(null, new Uint16Array(buf));
}
注意:以這種方式使用apply
意味着您可以達到參數限制(大約 16000 個元素左右),然后您將不得不循環遍歷數組元素。
我意識到這是一個非常古老的問題,但我想添加一個更多可能的案例/解決方案,因為我是通過搜索找到這個問題的:
我想要一個FileReader.readAsBinaryString()
的異步/等待版本,因為我是一個反復無常的人,回調接口讓我很煩:
// Suppose `file` exists
let fr = new FileReader()
let string1
fr.onload = ({ target: { result }}) => string1 = result
fr.readAsBinaryString(file)
console.log(string1)
此外,MDN 表示FileReader.readAsBinaryString()
的存在只是為了向后兼容,建議使用FileReader.readAsArrayBuffer()
。
Blob
/ File
上有一些新方法可以為您提供text 、 ArrayBuffer
和stream s,但沒有二進制字符串。 聽從 MDN 的建議,我認為我們可以使用新方法將 go 從ArrayBuffer
轉換為二進制字符串,而且我們確實可以:
// Again, suppose `file` exists
let ab, bufferToString, string2
bufferToString = (buffer) => {
const bytes = new Uint8Array(buffer)
return bytes.reduce((string, byte) => (string + String.fromCharCode(byte)), "")
}
ab = await file.arrayBuffer()
string2 = bufferToString(ab)
console.log(string2)
假設這是在同一個瀏覽器控制台中完成的:
string1 === string2 // true
這是聰明還是愚蠢留給讀者。
function string2Bin(s) {
var b = new Array();
var last = s.length;
for (var i = 0; i < last; i++) {
var d = s.charCodeAt(i);
if (d < 128)
b[i] = dec2Bin(d);
else {
var c = s.charAt(i);
alert(c + ' is NOT an ASCII character');
b[i] = -1;
}
}
return b;
}
function dec2Bin(d) {
var b = '';
for (var i = 0; i < 8; i++) {
b = (d%2) + b;
d = Math.floor(d/2);
}
return b;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.