Jacascript base64 не декодировать по мере необходимости - PullRequest
0 голосов
/ 31 марта 2020

У меня есть эта строка в моем html коде:

eyJzaW1wbGVUZXh0Ijoi8J+NjCBTVU1NRVIgU0VUIDIwMTkg8J+QnSBERSBMQSBLQVJJTkEg4pqhINeh15gg16fXmdelIDIwMTkg8J+MvSJ9

Он представляет этот код в Base64:

{"simpleText":"? SUMMER SET 2019 ? DE LA KARINA ⚡ סט קיץ 2019 ?"}

Я столкнулся с проблемой при использовании моего декодирования Base64 Метод:

function decode(data) {
var value, code, idx = 0, bytes = [], leftbits = 0, leftdata = 0;
var binTable = [
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
];

var padding = '=';

for (idx = 0; idx < data.length; idx++) {
  code = data.charCodeAt(idx);
  value = binTable[code & 0x7F];

  if (-1 === value) {
    log("WARN: Illegal characters (code=" + code + ") in position " + idx);
  } else {
    leftdata = (leftdata << 6) | value;
    leftbits += 6;

    if (leftbits >= 8) {
      leftbits -= 8;
      if (padding !== data.charAt(idx)) {
        bytes.push((leftdata >> leftbits) & 0xFF);
      }
      leftdata &= (1 << leftbits) - 1;
    }
  }
}

if (leftbits) {
  log("ERROR: Corrupted base64 string");
  return null;
}

return utf8Decode(bytes);
}

, который дал мне эту строку:

{"simpleText":"ߍ젓UMMER SET 2019 ߐ�E LA KARINA ⚡ סט קיץ 2019 ߌ�

Я знаю, что рекомендуется использовать функцию atob, но, поскольку это вызвало у меня другие проблемы, я предпочитаю использовать это Вместо этого, любая идея, почему он не работает с Emoji внутри строки.

Спасибо!

Ответы [ 3 ]

1 голос
/ 31 марта 2020

Вы можете использовать encodeURIComponent / decodeURIComponent с экранированной строкой, чтобы вернуть ваши смайлики. (см. здесь для получения дополнительной информации http://ecmanaut.blogspot.com/2006/07/encoding-decoding-utf8-in-javascript.html)

Вот пример кода, показывающий кодирование / декодирование с вашими данными: https://jsbin.com/wusokawacu/edit?js, консоль

const string = {"simpleText":"? SUMMER SET 2019 ? DE LA KARINA ⚡ סט קיץ 2019 ?"}


function utf8_to_b64(str) {
  return window.btoa(unescape(encodeURIComponent(str)));
}

function b64_to_utf8(str) {
  return decodeURIComponent(escape(window.atob(str)));
}

const encoded = utf8_to_b64(JSON.stringify(string));
const decoded = b64_to_utf8(encoded);
1 голос
/ 31 марта 2020

Я думаю, что ваша проблема не в функции decode(), а в функции utf8Decode(), используемой внутри.

Однако вы не предоставили его, поэтому я написал один, и он дает правильный результат для вашей строки (вы можете увидеть {"simpleText":"? SUMMER SET 2019 ? DE LA KARINA ⚡ סט קיץ 2019 ?"} в консоли):

const example = "eyJzaW1wbGVUZXh0Ijoi8J+NjCBTVU1NRVIgU0VUIDIwMTkg8J+QnSBERSBMQSBLQVJJTkEg4pqhINeh15gg16fXmdelIDIwMTkg8J+MvSJ9";

function decode(data) {
  var value, code, idx = 0, bytes = [], leftbits = 0, leftdata = 0;
  var binTable = [
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
    -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
    52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
    -1, 0, 1, 2,  3, 4, 5, 6,  7, 8, 9,10, 11,12,13,14,
    15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
    -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
    41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
  ];

  var padding = '=';

  for (idx = 0; idx < data.length; idx++) {
    code = data.charCodeAt(idx);
    value = binTable[code & 0x7F];

    if (-1 === value) {
      console.log("WARN: Illegal characters (code=" + code + ") in position " + idx);
    } else {
      leftdata = (leftdata << 6) | value;
      leftbits += 6;

      if (leftbits >= 8) {
        leftbits -= 8;
        if (padding !== data.charAt(idx)) {
          bytes.push((leftdata >> leftbits) & 0xFF);
        }
        leftdata &= (1 << leftbits) - 1;
      }
    }
  }

  if (leftbits) {
    console.log("ERROR: Corrupted base64 string");
    return null;
  }

  return utf8Decode(bytes);
}

function utf8Decode(bytes) {
     return new TextDecoder().decode(new Uint8Array(bytes));
}

const result = decode(example);
console.log(result);
0 голосов
/ 31 марта 2020

Я знаю, что вы сказали, что не хотите использовать встроенную функцию atob

, но пробовали ли вы так:

let encodedData = 'eyJzaW1wbGVUZXh0Ijoi8J+NjCBTVU1NRVIgU0VUIDIwMTkg8J+QnSBERSBMQSBLQVJJTkEg4pqhINeh15gg16fXmdelIDIwMTkg8J+MvSJ9';

let decodedData = decodeURIComponent(escape(window.atob(encodedData)));
console.log(decodedData); // will print your data with the emojis

Если вы все еще хотите реализовать ее самостоятельно посмотрите в этом пакете: https://github.com/dankogai/js-base64/blob/master/base64.js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...