วิธีแปลง String เป็น Bytearray


92

ฉันจะแปลงสตริงใน bytearray โดยใช้ JavaScript ได้อย่างไร ผลลัพธ์ควรเทียบเท่ากับรหัส C # ด้านล่าง

UnicodeEncoding encoding = new UnicodeEncoding();
byte[] bytes = encoding.GetBytes(AnyString);

เนื่องจาก UnicodeEncoding เป็นค่าเริ่มต้นของ UTF-16 ที่มี Little-Endianness

แก้ไข:ฉันมีข้อกำหนดในการจับคู่ฝั่งไคลเอ็นต์ที่สร้างโดย bytearray กับฝั่งเซิร์ฟเวอร์โดยใช้รหัส C # ด้านบน


3
javascript ไม่เป็นที่รู้จักกันดีที่สุดว่าใช้งานง่ายกับ BLOBs ทำไมคุณไม่ส่งสตริงใน JSON
Marc Gravell

บางทีลองดูที่นี่ก็ได้ ..
V4Vendetta

2
สตริง Javascript คือ UTF-16 หรือคุณรู้จักสิ่งนี้แล้ว?
Kevin

2
ก่อนอื่นทำไมคุณต้องแปลงสิ่งนี้ในจาวาสคริปต์?
BreakHead

17
ไม่ได้เข้ารหัสสตริง ใช่ภายในจะแสดงเป็นไบต์และมีการเข้ารหัส แต่โดยพื้นฐานแล้วไม่มีความหมายในระดับการเขียนสคริปต์ สตริงคือคอลเลกชันเชิงตรรกะของอักขระ ในการเข้ารหัสอักขระคุณต้องเลือกรูปแบบการเข้ารหัสอย่างชัดเจนซึ่งคุณสามารถใช้เพื่อแปลงรหัสอักขระแต่ละตัวให้เป็นลำดับไบต์ตั้งแต่หนึ่งไบต์ขึ้นไป คำตอบสำหรับคำถามนี้ด้านล่างคือขยะเนื่องจากพวกเขาเรียกว่า charCodeAt และรวมค่าไว้ในอาร์เรย์ที่เรียกว่า "ไบต์" สวัสดี! charCodeAt สามารถส่งคืนค่าที่มากกว่า 255 ดังนั้นจึงไม่ใช่ไบต์!
Triynko

คำตอบ:


21

ใน C # รันสิ่งนี้

UnicodeEncoding encoding = new UnicodeEncoding();
byte[] bytes = encoding.GetBytes("Hello");

จะสร้างอาร์เรย์ด้วย

72,0,101,0,108,0,108,0,111,0

อาร์เรย์ไบต์

สำหรับอักขระที่รหัสมากกว่า 255 จะมีลักษณะดังนี้

อาร์เรย์ไบต์

หากคุณต้องการพฤติกรรมที่คล้ายกันมากใน JavaScript คุณสามารถทำได้ (v2 เป็นโซลูชันที่มีประสิทธิภาพมากกว่าเล็กน้อยในขณะที่เวอร์ชันดั้งเดิมจะใช้งานได้กับ 0x00 ~ 0xff เท่านั้น)

var str = "Hello竜";
var bytes = []; // char codes
var bytesv2 = []; // char codes

for (var i = 0; i < str.length; ++i) {
  var code = str.charCodeAt(i);
  
  bytes = bytes.concat([code]);
  
  bytesv2 = bytesv2.concat([code & 0xff, code / 256 >>> 0]);
}

// 72, 101, 108, 108, 111, 31452
console.log('bytes', bytes.join(', '));

// 72, 0, 101, 0, 108, 0, 108, 0, 111, 0, 220, 122
console.log('bytesv2', bytesv2.join(', '));


1
ฉันได้ลองแล้ว แต่สิ่งนี้ให้ผลลัพธ์ที่แตกต่างจากรหัส C # ด้านบน เช่นเดียวกับกรณีนี้อาร์เรย์ไบต์เอาต์พุตรหัส C # คือ = 72,0,101,0,108,0,108,0,111,0 ฉันมีข้อกำหนดที่จะจับคู่ทั้งสองอย่างเพื่อไม่ให้ทำงาน
shas

2
ฉันทดสอบก่อนหน้านี้บน Firefox 4 เท่านั้นเวอร์ชันที่อัปเดตได้รับการทดสอบบน Firefox 4, Chrome 13 และ IE9
BrunoLM

41
โปรดทราบว่าหากสตริงมีอักขระยูนิโคด charCodeAt (i) จะเป็น> 255 ซึ่งอาจไม่ใช่สิ่งที่คุณต้องการ
broofa

23
ใช่นี่ไม่ถูกต้อง charCodeAt ไม่ส่งคืนไบต์ ไม่มีเหตุผลที่จะผลักค่าที่มากกว่า 255 ไปยังอาร์เรย์ที่เรียกว่า "ไบต์" ทำให้เข้าใจผิดมาก ฟังก์ชั่นนี้ไม่ได้ทำการเข้ารหัสเลยเพียงแค่ใส่รหัสอักขระลงในอาร์เรย์
Triynko

1
ฉันไม่เข้าใจว่าทำไมคำตอบนี้จึงถูกทำเครื่องหมายว่าถูกต้องเนื่องจากไม่ได้เข้ารหัสอะไรเลย
AB

34

หากคุณกำลังมองหาโซลูชันที่ใช้ได้ใน node.js คุณสามารถใช้สิ่งนี้:

var myBuffer = [];
var str = 'Stack Overflow';
var buffer = new Buffer(str, 'utf16le');
for (var i = 0; i < buffer.length; i++) {
    myBuffer.push(buffer[i]);
}

console.log(myBuffer);

3
นี่ใช้สำหรับ node.js แต่ฉันคิดว่าคำถามกำลังมองหาวิธีแก้ปัญหาที่ใช้งานได้ในเบราว์เซอร์ อย่างไรก็ตามมันทำงานได้อย่างถูกต้องซึ่งแตกต่างจากคำตอบอื่น ๆ ส่วนใหญ่สำหรับคำถามนี้ดังนั้น +1
Daniel Cassidy

ใช้งานได้ แต่โค้ดที่ง่ายกว่ามากคือ function convertString (myString) {var myBuffer = new Buffer (myString, 'utf16le'); console.log (myBuffer); คืน myBuffer; }
Philip Rutovitz

16

ฉันคิดว่า C # และ Java สร้างอาร์เรย์ไบต์ที่เท่ากัน หากคุณมีอักขระที่ไม่ใช่ ASCII การเพิ่ม 0 เพิ่มเติมนั้นไม่เพียงพอตัวอย่างของฉันมีอักขระพิเศษบางตัว:

var str = "Hell ö € Ω 𝄞";
var bytes = [];
var charCode;

for (var i = 0; i < str.length; ++i)
{
    charCode = str.charCodeAt(i);
    bytes.push((charCode & 0xFF00) >> 8);
    bytes.push(charCode & 0xFF);
}

alert(bytes.join(' '));
// 0 72 0 101 0 108 0 108 0 32 0 246 0 32 32 172 0 32 3 169 0 32 216 52 221 30

ฉันไม่รู้ว่า C # วาง BOM (Byte Order Marks) หรือไม่ แต่ถ้าใช้ UTF-16 Java String.getBytesจะเพิ่มไบต์ต่อไปนี้: 254 255

String s = "Hell ö € Ω ";
// now add a character outside the BMP (Basic Multilingual Plane)
// we take the violin-symbol (U+1D11E) MUSICAL SYMBOL G CLEF
s += new String(Character.toChars(0x1D11E));
// surrogate codepoints are: d834, dd1e, so one could also write "\ud834\udd1e"

byte[] bytes = s.getBytes("UTF-16");
for (byte aByte : bytes) {
    System.out.print((0xFF & aByte) + " ");
}
// 254 255 0 72 0 101 0 108 0 108 0 32 0 246 0 32 32 172 0 32 3 169 0 32 216 52 221 30

แก้ไข:

เพิ่มอักขระพิเศษ (U + 1D11E) MUSICAL SYMBOL G CLEF (นอก BPM ดังนั้นไม่เพียงแค่ 2 ไบต์ใน UTF-16 แต่ 4

JavaScript เวอร์ชันปัจจุบันใช้ "UCS-2" ภายในสัญลักษณ์นี้จึงใช้พื้นที่ 2 อักขระปกติ

ฉันไม่แน่ใจ แต่เมื่อใช้charCodeAtดูเหมือนว่าเราจะได้รับจุดรหัสตัวแทนที่ใช้ใน UTF-16 ดังนั้นอักขระที่ไม่ใช่ BPM จึงได้รับการจัดการอย่างถูกต้อง

ปัญหานี้ไม่สำคัญอย่างแน่นอน อาจขึ้นอยู่กับเวอร์ชันและเอ็นจิ้น JavaScript ที่ใช้ ดังนั้นหากคุณต้องการโซลูชันที่เชื่อถือได้คุณควรดูที่:


1
ยังคงไม่ใช่คำตอบที่สมบูรณ์ UTF16 เป็นการเข้ารหัสความยาวตัวแปรที่ใช้ส่วน 16 บิตเพื่อแสดงอักขระ อักขระเดี่ยวจะถูกเข้ารหัสเป็น 2 ไบต์หรือ 4 ไบต์ขึ้นอยู่กับว่าค่ารหัสตัวอักษรมีขนาดใหญ่เพียงใด เนื่องจากฟังก์ชั่นนี้เขียนได้สูงสุด 2 ไบต์จึงไม่สามารถจัดการกับจุดรหัสอักขระ Unicode ทั้งหมดและไม่ใช่การนำการเข้ารหัส UTF16 ไปใช้โดยสมบูรณ์ไม่ใช่ด้วยการยิงระยะไกล
Triynko

@Triynko หลังจากแก้ไขและทดสอบแล้วคุณยังคิดว่านี่ไม่ใช่คำตอบที่สมบูรณ์หรือไม่? ถ้าใช่คุณมีคำตอบหรือไม่?
hgoebl

2
@Triynko คุณถูกเพียงครึ่งเดียว แต่จริงๆแล้วคำตอบนี้ทำงานได้อย่างถูกต้อง สตริง JavaScript ไม่ใช่ลำดับของ Unicode Code Points ซึ่งเป็นลำดับของหน่วยรหัส UTF-16 แม้จะมีชื่อ แต่charCodeAtส่งกลับหน่วยรหัส UTF-16 ในช่วง 0-65535 อักขระที่อยู่นอกช่วง 2 ไบต์จะแสดงเป็นคู่ตัวแทนเช่นเดียวกับใน UTF-16 (อย่างไรก็ตามนี่เป็นความจริงสำหรับสตริงในภาษาอื่น ๆ รวมถึง Java และ C #)
Daniel Cassidy

อย่างไรก็ตาม(charCode & 0xFF00) >> 8มันซ้ำซ้อนคุณไม่จำเป็นต้องมาสก์ก่อนที่จะขยับ
Patrick Roberts

16

วิธีที่ง่ายที่สุดในปี 2018 ควรเป็นTextEncoderแต่องค์ประกอบที่ส่งคืนไม่ใช่อาร์เรย์ไบต์มันคือ Uint8Array (และไม่ใช่ทุกเบราว์เซอร์ที่รองรับ)

let utf8Encode = new TextEncoder();
utf8Encode.encode("eee")
> Uint8Array [ 101, 101, 101 ]

นี่เป็นเรื่องแปลก ฉันไม่คิดว่าจะใช้ชื่อตัวแปรที่แตกต่างกันเพราะ utf8Decode และ utf8Encode จะใช้งานได้
Unihedron

คุณสามารถใช้TextDecodernew TextDecoder().decode(new TextEncoder().encode(str)) == strเพื่อถอดรหัส:
Fons

ตารางสนับสนุนของTextEncoder: caniuse
Fons

11

UTF-16 ไบต์อาร์เรย์

JavaScript เข้ารหัสสตริงเป็นUTF-16เช่นเดียวกับ C # UnicodeEncodingดังนั้นอาร์เรย์ไบต์ควรตรงกันทุกประการโดยใช้charCodeAt()และแยกคู่ไบต์ที่ส่งคืนแต่ละคู่ออกเป็น 2 ไบต์แยกกันดังใน:

function strToUtf16Bytes(str) {
  const bytes = [];
  for (ii = 0; ii < str.length; ii++) {
    const code = str.charCodeAt(ii); // x00-xFFFF
    bytes.push(code & 255, code >> 8); // low, high
  }
  return bytes;
}

ตัวอย่างเช่น:

strToUtf16Bytes('🌵'); 
// [ 60, 216, 53, 223 ]

อย่างไรก็ตามหากคุณต้องการรับอาร์เรย์ UTF-8 ไบต์คุณต้องแปลงรหัสไบต์

UTF-8 ไบต์อาร์เรย์

วิธีแก้ปัญหานี้ค่อนข้างไม่สำคัญ แต่ฉันใช้โค้ดด้านล่างในสภาพแวดล้อมการผลิตที่มีปริมาณการใช้งานสูงและประสบความสำเร็จอย่างมาก ( ต้นฉบับ )

นอกจากนี้สำหรับผู้อ่านที่สนใจฉันได้เผยแพร่ตัวช่วย Unicode ของฉันที่ช่วยฉันทำงานกับความยาวสตริงที่รายงานโดยภาษาอื่นเช่น PHP

/**
 * Convert a string to a unicode byte array
 * @param {string} str
 * @return {Array} of bytes
 */
export function strToUtf8Bytes(str) {
  const utf8 = [];
  for (let ii = 0; ii < str.length; ii++) {
    let charCode = str.charCodeAt(ii);
    if (charCode < 0x80) utf8.push(charCode);
    else if (charCode < 0x800) {
      utf8.push(0xc0 | (charCode >> 6), 0x80 | (charCode & 0x3f));
    } else if (charCode < 0xd800 || charCode >= 0xe000) {
      utf8.push(0xe0 | (charCode >> 12), 0x80 | ((charCode >> 6) & 0x3f), 0x80 | (charCode & 0x3f));
    } else {
      ii++;
      // Surrogate pair:
      // UTF-16 encodes 0x10000-0x10FFFF by subtracting 0x10000 and
      // splitting the 20 bits of 0x0-0xFFFFF into two halves
      charCode = 0x10000 + (((charCode & 0x3ff) << 10) | (str.charCodeAt(ii) & 0x3ff));
      utf8.push(
        0xf0 | (charCode >> 18),
        0x80 | ((charCode >> 12) & 0x3f),
        0x80 | ((charCode >> 6) & 0x3f),
        0x80 | (charCode & 0x3f),
      );
    }
  }
  return utf8;
}

และสิ่งที่ผกผันของสิ่งนี้คืออะไร?
simbo1905

ฉันจะอธิบายฟังก์ชันผกผันว่า "แปลงอาร์เรย์ UTF-8 ไบต์เป็นสตริง UTF-16 ดั้งเดิม" ฉันไม่เคยสร้างสิ่งผกผัน ใน myc env ฉันลบโค้ดนี้โดยเปลี่ยนเอาต์พุต API เป็นช่วงอักขระแทนที่จะเป็นช่วงไบต์จากนั้นฉันใช้รูนเพื่อแยกวิเคราะห์ช่วง
jchook

ฉันขอแนะนำว่านี่ควรเป็นคำตอบที่ยอมรับสำหรับคำถามนี้
LeaveTheCapital

10

แรงบันดาลใจจากคำตอบของ @ hgoebl รหัสของเขาคือ UTF-16 และฉันต้องการบางอย่างสำหรับ US-ASCII นี่คือคำตอบที่สมบูรณ์ยิ่งขึ้นซึ่งครอบคลุม US-ASCII, UTF-16 และ UTF-32

/**@returns {Array} bytes of US-ASCII*/
function stringToAsciiByteArray(str)
{
    var bytes = [];
   for (var i = 0; i < str.length; ++i)
   {
       var charCode = str.charCodeAt(i);
      if (charCode > 0xFF)  // char > 1 byte since charCodeAt returns the UTF-16 value
      {
          throw new Error('Character ' + String.fromCharCode(charCode) + ' can\'t be represented by a US-ASCII byte.');
      }
       bytes.push(charCode);
   }
    return bytes;
}
/**@returns {Array} bytes of UTF-16 Big Endian without BOM*/
function stringToUtf16ByteArray(str)
{
    var bytes = [];
    //currently the function returns without BOM. Uncomment the next line to change that.
    //bytes.push(254, 255);  //Big Endian Byte Order Marks
   for (var i = 0; i < str.length; ++i)
   {
       var charCode = str.charCodeAt(i);
       //char > 2 bytes is impossible since charCodeAt can only return 2 bytes
       bytes.push((charCode & 0xFF00) >>> 8);  //high byte (might be 0)
       bytes.push(charCode & 0xFF);  //low byte
   }
    return bytes;
}
/**@returns {Array} bytes of UTF-32 Big Endian without BOM*/
function stringToUtf32ByteArray(str)
{
    var bytes = [];
    //currently the function returns without BOM. Uncomment the next line to change that.
    //bytes.push(0, 0, 254, 255);  //Big Endian Byte Order Marks
   for (var i = 0; i < str.length; i+=2)
   {
       var charPoint = str.codePointAt(i);
       //char > 4 bytes is impossible since codePointAt can only return 4 bytes
       bytes.push((charPoint & 0xFF000000) >>> 24);
       bytes.push((charPoint & 0xFF0000) >>> 16);
       bytes.push((charPoint & 0xFF00) >>> 8);
       bytes.push(charPoint & 0xFF);
   }
    return bytes;
}

UTF-8 เป็นความยาวตัวแปรและไม่รวมอยู่ด้วยเพราะฉันจะต้องเขียนการเข้ารหัสด้วยตัวเอง UTF-8 และ UTF-16 เป็นความยาวตัวแปร UTF-8, UTF-16 และ UTF-32 มีจำนวนบิตขั้นต่ำตามที่ชื่อระบุ หากอักขระ UTF-32 มีจุดรหัสเป็น 65 นั่นหมายความว่ามี 3 นำหน้า 0 แต่รหัสเดียวกันสำหรับ UTF-16 มีเพียง 1 นำหน้าเท่านั้นในทางกลับกัน US-ASCII คือความกว้างคงที่ 8 บิตซึ่งหมายความว่าสามารถแปลเป็นไบต์ได้โดยตรง

String.prototype.charCodeAtส่งคืนจำนวนสูงสุด 2 ไบต์และตรงกับ UTF-16 ทุกประการ อย่างไรก็ตามสำหรับ UTF-32 String.prototype.codePointAtเป็นสิ่งจำเป็นซึ่งเป็นส่วนหนึ่งของข้อเสนอ ECMAScript 6 (Harmony) เนื่องจาก charCodeAt ส่งคืน 2 ไบต์ซึ่งเป็นอักขระที่เป็นไปได้มากกว่าที่ US-ASCII สามารถแสดงได้ฟังก์ชันstringToAsciiByteArrayจะโยนในกรณีดังกล่าวแทนที่จะแบ่งอักขระออกเป็นครึ่งหนึ่งและใช้ไบต์อย่างใดอย่างหนึ่งหรือทั้งสองอย่าง

โปรดทราบว่าคำตอบนี้ไม่สำคัญเพราะการเข้ารหัสอักขระไม่ใช่เรื่องสำคัญ ชนิดของอาร์เรย์ไบต์ที่คุณต้องการขึ้นอยู่กับอักขระการเข้ารหัสที่คุณต้องการให้ไบต์เหล่านั้นเป็นตัวแทน

javascript มีตัวเลือกในการใช้ภายใน UTF-16 หรือ UCS-2 แต่เนื่องจากมีวิธีการที่เหมือนกับ UTF-16 ฉันไม่เห็นว่าทำไมเบราว์เซอร์ใด ๆ ถึงใช้ UCS-2 ดูเพิ่มเติมที่https://mathiasbynens.be/notes/javascript-encoding

ใช่ฉันรู้ว่าคำถามนี้มีอายุ 4 ปี แต่ฉันต้องการคำตอบนี้สำหรับตัวเอง


โหนดผลบัฟเฟอร์สำหรับ'02'เป็น[ 48, 0, 50, 0 ]ที่เป็นของคุณกลับมาทำงานstringToUtf16ByteArray [ 0, 48, 0, 50 ]อันไหนที่ถูก?
pkyeck

@pkyeck ฟังก์ชัน stringToUtf16ByteArray ของฉันด้านบนจะคืนค่า UTF-16 BE โดยไม่มี BOM ตัวอย่างที่คุณให้จากโหนดคือ UTF-16 LE ที่ไม่มี BOM ฉันเคยคิดว่า Big-endian ธรรมดากว่า little-endian แต่อาจจะผิดก็ได้
SkySpiral7

2

เนื่องจากฉันไม่สามารถแสดงความคิดเห็นเกี่ยวกับคำตอบได้ฉันจึงสร้างคำตอบของ Jin Izzraeel

var myBuffer = [];
var str = 'Stack Overflow';
var buffer = new Buffer(str, 'utf16le');
for (var i = 0; i < buffer.length; i++) {
    myBuffer.push(buffer[i]);
}

console.log(myBuffer);

โดยบอกว่าคุณสามารถใช้สิ่งนี้ได้หากคุณต้องการใช้บัฟเฟอร์ Node.js ในเบราว์เซอร์ของคุณ

https://github.com/feross/buffer

ดังนั้นการคัดค้านของ Tom Stickel จึงไม่ถูกต้องและคำตอบนั้นเป็นคำตอบที่ถูกต้อง


1
String.prototype.encodeHex = function () {
    return this.split('').map(e => e.charCodeAt())
};

String.prototype.decodeHex = function () {    
    return this.map(e => String.fromCharCode(e)).join('')
};

4
จะเป็นประโยชน์หากคุณระบุข้อความบางส่วนพร้อมกับรหัสเพื่ออธิบายว่าเหตุใดจึงอาจเลือกแนวทางนี้มากกว่าคำตอบอื่น ๆ
NightOwl888

วิธีนี้ง่ายกว่าวิธีอื่น แต่ทำแบบเดียวกันนั่นคือเหตุผลที่ฉันไม่ได้เขียนอะไรเลย
Fabio Maciel

encodeHexจะส่งคืนอาร์เรย์ของตัวเลข 16 บิตไม่ใช่ไบต์
Pavlo

0

ทางออกที่ดีที่สุดที่ฉันคิดไว้ ณ จุดนั้น (แม้ว่าส่วนใหญ่จะเป็นน้ำมันดิบ) คือ:

String.prototype.getBytes = function() {
    var bytes = [];
    for (var i = 0; i < this.length; i++) {
        var charCode = this.charCodeAt(i);
        var cLen = Math.ceil(Math.log(charCode)/Math.log(256));
        for (var j = 0; j < cLen; j++) {
            bytes.push((charCode << (j*8)) & 0xFF);
        }
    }
    return bytes;
}

แม้ว่าฉันสังเกตว่าคำถามนี้อยู่ที่นี่มานานกว่าหนึ่งปีแล้ว


2
สิ่งนี้ทำงานไม่ถูกต้อง ตรรกะอักขระความยาวตัวแปรไม่ถูกต้องไม่มีอักขระ 8 บิตใน UTF-16 แม้จะมีชื่อ แต่charCodeAtส่งคืนหน่วยรหัส UTF-16 16 บิตดังนั้นคุณไม่จำเป็นต้องใช้ตรรกะความยาวตัวแปรใด ๆ คุณสามารถเรียกใช้ charCodeAt แยกผลลัพธ์ออกเป็นสองไบต์ 8 บิตและบรรจุไว้ในอาร์เรย์เอาต์พุต (ไบต์ลำดับต่ำสุดก่อนเนื่องจากคำถามถามหา UTF-16LE)
Daniel Cassidy

0

ฉันรู้ว่าคำถามเกือบ 4 ปี แต่นี่คือสิ่งที่ทำงานได้อย่างราบรื่นกับฉัน:

String.prototype.encodeHex = function () {
  var bytes = [];
  for (var i = 0; i < this.length; ++i) {
    bytes.push(this.charCodeAt(i));
  }
  return bytes;
};

Array.prototype.decodeHex = function () {    
  var str = [];
  var hex = this.toString().split(',');
  for (var i = 0; i < hex.length; i++) {
    str.push(String.fromCharCode(hex[i]));
  }
  return str.toString().replace(/,/g, "");
};

var str = "Hello World!";
var bytes = str.encodeHex();

alert('The Hexa Code is: '+bytes+' The original string is:  '+bytes.decodeHex());

หรือหากคุณต้องการทำงานกับสตริงเท่านั้นและไม่มี Array คุณสามารถใช้:

String.prototype.encodeHex = function () {
  var bytes = [];
  for (var i = 0; i < this.length; ++i) {
    bytes.push(this.charCodeAt(i));
  }
  return bytes.toString();
};

String.prototype.decodeHex = function () {    
  var str = [];
  var hex = this.split(',');
  for (var i = 0; i < hex.length; i++) {
    str.push(String.fromCharCode(hex[i]));
  }
  return str.toString().replace(/,/g, "");
};

var str = "Hello World!";
var bytes = str.encodeHex();

alert('The Hexa Code is: '+bytes+' The original string is:  '+bytes.decodeHex());


2
งานประเภทนี้ แต่ทำให้เข้าใจผิดอย่างมาก bytesอาร์เรย์ไม่ได้มี 'ไบต์' มันมีตัวเลข 16 บิตซึ่งเป็นตัวแทนของสตริง UTF-16 หน่วยรหัส นี่เกือบจะเป็นสิ่งที่คำถามถาม แต่เกิดขึ้นโดยบังเอิญเท่านั้น
Daniel Cassidy

-1

นี่คือฟังก์ชั่นเดียวกับที่ @BrunoLM โพสต์ที่แปลงเป็นฟังก์ชัน String ต้นแบบ:

String.prototype.getBytes = function () {
  var bytes = [];
  for (var i = 0; i < this.length; ++i) {
    bytes.push(this.charCodeAt(i));
  }
  return bytes;
};

หากคุณกำหนดฟังก์ชันดังกล่าวคุณสามารถเรียกใช้เมธอด. getBytes () บนสตริงใดก็ได้:

var str = "Hello World!";
var bytes = str.getBytes();

31
สิ่งนี้ยังไม่ถูกต้องเช่นเดียวกับคำตอบที่อ้างอิง charCodeAt ไม่ส่งคืนไบต์ ไม่มีเหตุผลที่จะผลักค่าที่มากกว่า 255 ไปยังอาร์เรย์ที่เรียกว่า "ไบต์" ทำให้เข้าใจผิดมาก ฟังก์ชั่นนี้ไม่ได้ทำการเข้ารหัสเลยเพียงแค่ใส่รหัสอักขระลงในอาร์เรย์ ในการเข้ารหัส UTF16 คุณต้องตรวจสอบโค้ดตัวอักษรตัดสินใจว่าคุณจะต้องแทนด้วย 2 ไบต์หรือ 4 ไบต์ (เนื่องจาก UTF16 เป็นการเข้ารหัสความยาวตัวแปร) จากนั้นจึงเขียนแต่ละไบต์ไปยังอาร์เรย์ทีละรายการ
Triynko

8
นอกจากนี้การแก้ไขต้นแบบของชนิดข้อมูลเนทีฟยังเป็นวิธีปฏิบัติที่ไม่ดี
Andrew Lundin

@AndrewLundin ที่ขัดจังหวะ ... พูดว่าใคร?
Jerther


-3

คุณไม่จำเป็นต้องมีขีดล่างเพียงแค่ใช้แผนที่ในตัว:

var string = 'Hello World!';

document.write(string.split('').map(function(c) { return c.charCodeAt(); }));


1
สิ่งนี้ส่งคืนอาร์เรย์ของตัวเลข 16 บิตที่แสดงสตริงเป็นลำดับของจุดรหัส UTF-16 นั่นไม่ใช่สิ่งที่ OP ขอ แต่อย่างน้อยมันก็พาคุณไปที่นั่น
Daniel Cassidy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.