如何在 JavaScript 中使用字节数组将字符串转换为 base64 编码?
Posted
技术标签:
【中文标题】如何在 JavaScript 中使用字节数组将字符串转换为 base64 编码?【英文标题】:How to convert a string to base64 encoding using byte array in JavaScript? 【发布时间】:2019-08-16 18:51:01 【问题描述】:我有下面的 .NET 代码通过首先将字符串转换为字节数组来将字符串转换为 Base64 编码。我在 Stack Overflow 上尝试了不同的答案来转换字节数组中的字符串,然后使用 btoa() 函数在 javascript 中进行 base64 编码。但是,我没有得到下面共享的确切编码值。
对于字符串值,
BBFDC43D-4890-4558-BB89-50D802014A97
我需要Base64编码,
PcT9u5BIWEW7iVDYAgFKlw==
.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==
目前,我尝试使用以下代码,但没有产生预期的结果:
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=
【问题讨论】:
能否也提供你使用的JS代码? 可能重复来自:***.com/questions/246801/… 这不是那个问题的重复,因为我正在使用 btoa() 进行编码,但我担心这里的字节数组。 您确定 PcT9u5BIWEW7iVDYAgFKlw== 是字符串 BBFDC43D-4890-4558-BB89-50D802014A97 的 base64 表示形式 您应该发布您的 javascript 代码。同样,正如我之前所说,您的代码不会将该字符串转换为 base64,而是将该字符串作为一组十六进制值,将其转换为以 10 为基数,然后将生成的字节数组编码为以 64 为基数 【参考方案1】:您的问题是由以下原因引起的:
btoa()
使用 ASCII 编码
guid.ToByteArray();
不使用 ASCII 编码
如果你像这样修改你的 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);
你会得到以下输出:
QkJGREM0M0QtNDg5MC00NTU4LUJCODktNTBEODAyMDE0QTk3
与btoa()
函数返回的字符串相同:
var rawString = "BBFDC43D-4890-4558-BB89-50D802014A97";
var b64encoded = btoa(rawString);
console.log(b64encoded);
输出:
QkJGREM0M0QtNDg5MC00NTU4LUJCODktNTBEODAyMDE0QTk3
更新 - 由于您无法修改 C# 代码
您应该通过组合 Piotr's answer 和 this SO answer 来调整您的 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);
输出:
PcT9u5BIWEW7iVDYAgFKlw==
【讨论】:
ASCII 或 UTF8 在这里没有区别,因为在代码点 127 之前它们是相同的。 @marko 我无法更改 .NET 代码,因为它是旧代码。我只需要在 JS 中复制它。 @HimanshuAggarwal 我刚刚用您需要进行的 Javascript 修改更新了答案。 我一直在尝试扭转这种情况以根据需要倒退,但无法到达那里,有什么关于转换回来的建议吗?【参考方案2】:您的代码的问题在于 Guid 的表示。在 C# 代码中,您将“BBFDC43D-4890-4558-BB89-50D802014A97”转换为 128 位数字的 UUID。在 JavaScript 代码中,您正在做其他事情。您遍历字符串并计算字符串的字节数组。他们根本就不平等。 现在你必须选择
-
在 JS 中实现正确的 guid 转换(这可能会有所帮助:https://gist.github.com/daboxu/4f1dd0a254326ac2361f8e78f89e97ae)
在 C# 中计算字节数组的方法与在 JS 中相同
【讨论】:
【参考方案3】:您的字符串是一个十六进制值,用于创建 GUID。然后将 GUID 转换为字节数组:
Byte[] bytes = guid.ToByteArray();
GUID 是一个 16 字节的值,可以表示为十六进制值。当您将此 GUID 转换为字节数组时,您将获得 16 个字节的值,不是十六进制值的字节表示。
在提供的 JavaScript 函数中,您正在执行其他操作:您正在将字符串 直接 转换为字节数组。
在 C# 中,您可以使用 Encoding
:
String str = "BBFDC43D-4890-4558-BB89-50D802014A97";
Byte[] bytes = Encoding.UTF8.GetBytes(str);
【讨论】:
以上是关于如何在 JavaScript 中使用字节数组将字符串转换为 base64 编码?的主要内容,如果未能解决你的问题,请参考以下文章
如何仅使用 javascript 将图像转换为字节数组以将图像存储在 sql server 上?
如何将javascript中uint8array转成普通数组或字符串?