简体   繁体   English

如何在JavaScript中使用字节数组将字符串转换为base64编码?

[英]How to convert a string to base64 encoding using byte array in JavaScript?

I have the below .NET code to convert a string to Base64 encoding by first converting it to byte array. 我有以下.NET代码,首先将字符串转换为字节数组,即可将字符串转换为Base64编码。 I tried different answers on Stack Overflow to convert the string in byte array and then use btoa() function for base64 encoding in JavaScript. 我在Stack Overflow上尝试了不同的答案,以将字节数组转换为字符串,然后将btoa()函数用于JavaScript中的base64编码。 But, I'm not getting the exact encoded value as shared below. 但是,我没有得到下面共享的确切编码值。

For string value, 对于字符串值,

BBFDC43D-4890-4558-BB89-50D802014A97 BBFDC43D-4890-4558-BB89-50D802014A97

I need Base64 encoding as, 我需要Base64编码,

PcT9u5BIWEW7iVDYAgFKlw== PcT9u5BIWEW7iVDYAgFKlw ==

.NET code: .NET代码:

String str = "BBFDC43D-4890-4558-BB89-50D802014A97"
Guid guid = new Guid(str);
Console.WriteLine(guid);    // bbfdc43d-4890-4558-bb89-50d802014a97
Byte[] bytes = guid.ToByteArray();
Console.WriteLine(bytes);   // System.Byte[]
String s = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
Console.WriteLine(s);   // PcT9u5BIWEW7iVDYAgFKlw==

Currently, I tried with the below code, which is not producing the desired result: 目前,我尝试使用以下代码,但未产生预期的结果:

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;
}

const str = "BBFDC43D-4890-4558-BB89-50D802014A97";
const strByteArr = strToUtf8Bytes(str);
const strBase64 = btoa(strByteArr);
// NjYsNjYsNzAsNjgsNjcsNTIsNTEsNjgsNDUsNTIsNTYsNTcsNDgsNDUsNTIsNTMsNTMsNTYsNDUsNjYsNjYsNTYsNTcsNDUsNTMsNDgsNjgsNTYsNDgsNTAsNDgsNDksNTIsNjUsNTcsNTU=

The problem with your code is representation of Guid. 您的代码的问题是Guid的表示形式。 In C# code you are converting "BBFDC43D-4890-4558-BB89-50D802014A97" into UUID which is a 128-bit number. 在C#代码中,您正在将“ BBFDC43D-4890-4558-BB89-50D802014A97”转换为UUID,这是一个128位数字。 In JavaScript code, you are doing something else. 在JavaScript代码中,您正在做其他事情。 You iterate through the string and calculate a byte array of a string. 您遍历字符串并计算字符串的字节数组。 They are simply not equal. 他们根本不平等。 Now you have to options 现在您必须选择

  1. Implement proper guid conversion in JS (this may help: https://gist.github.com/daboxu/4f1dd0a254326ac2361f8e78f89e97ae ) 在JS中实现适当的guid转换(这可能会有所帮助: https : //gist.github.com/daboxu/4f1dd0a254326ac2361f8e78f89e97ae
  2. In C# calculate byte array in the same way as in JS 在C#中,以与JS中相同的方式计算字节数组

Your problem is caused by the following: 您的问题是由以下原因引起的:

  • btoa() is using ASCII encoding btoa()使用ASCII编码
  • guid.ToByteArray(); does not use ASCII encoding 不使用ASCII编码

If you modify your C# code like this: 如果您像这样修改C#代码:

String str = "BBFDC43D-4890-4558-BB89-50D802014A97";
//Guid guid = new Guid(str);
//Console.WriteLine(guid);
// bbfdc43d-4890-4558-bb89-50d802014a97
//Byte[] bytes = guid.ToByteArray();
byte[] bytes = System.Text.Encoding.ASCII.GetBytes(str);
//Console.WriteLine(bytes);   // System.Byte[]
String s = Convert.ToBase64String(bytes, Base64FormattingOptions.InsertLineBreaks);
Console.WriteLine(s);

You will get the following output: 您将获得以下输出:

QkJGREM0M0QtNDg5MC00NTU4LUJCODktNTBEODAyMDE0QTk3

Which will be the same string as the one returned from the btoa() function: 该字符串与从btoa()函数返回的字符串相同:

var rawString = "BBFDC43D-4890-4558-BB89-50D802014A97";
var b64encoded = btoa(rawString);
console.log(b64encoded);

Output: 输出:

QkJGREM0M0QtNDg5MC00NTU4LUJCODktNTBEODAyMDE0QTk3

UPDATE - Since you can't modify the C# code 更新-由于您无法修改C#代码

You should adapt your Javascript code by combining Piotr's answer and this SO answer 您应该通过结合Piotr的答案此SO答案来修改Javascript代码

function guidToBytes(guid) {
    var bytes = [];
    guid.split('-').map((number, index) => {
        var bytesInChar = index < 3 ? number.match(/.{1,2}/g).reverse() : number.match(/.{1,2}/g);
        bytesInChar.map((byte) => { bytes.push(parseInt(byte, 16)); })
    });
    return bytes;
}

function arrayBufferToBase64(buffer) {
    var binary = '';
    var bytes = new Uint8Array(buffer);
    var len = bytes.byteLength;
    for (var i = 0; i < len; i++) {
        binary += String.fromCharCode(bytes[i]);
    }
    return btoa(binary);
}

var str = "BBFDC43D-4890-4558-BB89-50D802014A97";
var guidBytes = guidToBytes(str);
var b64encoded = arrayBufferToBase64(guidBytes);
console.log(b64encoded);

Output: 输出:

PcT9u5BIWEW7iVDYAgFKlw==

Your string is a hexadecimal value, which you use to create a GUID. 您的字符串是一个十六进制值,可用于创建GUID。 Then you convert the GUID into a byte array with: 然后,使用以下命令将GUID转换为字节数组:

Byte[] bytes = guid.ToByteArray();

The GUID is a 16-byte value which can be represented as a hexadecimal value. GUID是一个16字节的值,可以表示为十六进制值。 When you convert this GUID into a byte array, you will get the 16 bytes of the value, not the byte representation of the hexadecimal value. 当您将此GUID转换为字节数组时,将获得该值的16个字节, 而不是十六进制值的字节表示形式。

In the provided JavaScript function you are doing something else: You are converting the string directly to a byte array. 在提供的JavaScript函数中,您正在执行其他操作:您正在将字符串直接转换为字节数组。

In C# you do the equivalent with an Encoding : 在C#中,您可以使用Encoding进行等效操作:

String str = "BBFDC43D-4890-4558-BB89-50D802014A97";
Byte[] bytes = Encoding.UTF8.GetBytes(str);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM