Как преобразовать строку в кодировку base64, используя байтовый массив в JavaScript? - PullRequest
0 голосов
/ 26 марта 2019

У меня есть приведенный ниже код .NET для преобразования строки в кодировку Base64, сначала преобразовав ее в байтовый массив. Я пробовал разные ответы в Stack Overflow, чтобы преобразовать строку в байтовом массиве, а затем использовать функцию btoa () для кодирования base64 в JavaScript. Но я не получаю точное закодированное значение, как указано ниже.

Для строкового значения,

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=

Ответы [ 3 ]

1 голос
/ 26 марта 2019

Ваша проблема вызвана следующим:

  • 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 #

Вы должны адаптировать свой код Javascript, комбинируя ответ Петра и этот ответ SO

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==
1 голос
/ 26 марта 2019

Проблема с вашим кодом - представление Guid.В коде C # вы конвертируете «BBFDC43D-4890-4558-BB89-50D802014A97» в UUID, который является 128-битным числом.В коде JavaScript вы делаете что-то еще.Вы перебираете строку и вычисляете байтовый массив строки.Они просто не равны.Теперь у вас есть опции

  1. Реализация правильного преобразования guid в JS (это может помочь: https://gist.github.com/daboxu/4f1dd0a254326ac2361f8e78f89e97ae)
  2. В C # вычислить байтовый массив так же, как в JS
0 голосов
/ 26 марта 2019

Ваша строка является шестнадцатеричным значением, которое вы используете для создания GUID.Затем вы конвертируете GUID в байтовый массив с помощью:

Byte[] bytes = guid.ToByteArray();

GUID - это 16-байтовое значение, которое может быть представлено в виде шестнадцатеричного значения.Когда вы конвертируете этот GUID в байтовый массив, вы получите 16 байтов значения, not байтовое представление шестнадцатеричного значения.

В предоставленной функции JavaScript вы что-то делаетеиначе: Вы преобразуете строку напрямую в байтовый массив.

В C # вы делаете эквивалент с Encoding:

String str = "BBFDC43D-4890-4558-BB89-50D802014A97";
Byte[] bytes = Encoding.UTF8.GetBytes(str);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...