Определите, находится ли строка в base64, используя JavaScript - PullRequest
20 голосов
/ 22 октября 2011

Я использую функцию window.atob('string') для декодирования строки из base64 в строку. Теперь мне интересно, есть ли способ проверить, что 'string' на самом деле является действительным base64? Я хотел бы получить уведомление, если строка не является base64, чтобы я мог выполнить другое действие.

Ответы [ 8 ]

45 голосов
/ 22 октября 2011

Если вы хотите проверить, может ли он быть декодирован или нет, вы можете просто попробовать расшифровать его и посмотреть, не удалось ли это:

try {
    window.atob(str);
} catch(e) {
    // something failed

    // if you want to be specific and only catch the error which means
    // the base 64 was invalid, then check for 'e.code === 5'.
    // (because 'DOMException.INVALID_CHARACTER_ERR === 5')
}
21 голосов
/ 03 декабря 2015

Это должно сработать.

function isBase64(str) {
    if (str ==='' || str.trim() ===''){ return false; }
    try {
        return btoa(atob(str)) == str;
    } catch (err) {
        return false;
    }
}
17 голосов
/ 25 января 2016

Опираясь на ответ @ atornblad, используя регулярное выражение для создания простого теста на истинность / ложность для проверки правильности base64, можно сделать следующее:

var base64regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;

base64regex.test("SomeStringObviouslyNotBase64Encoded...");             // FALSE
base64regex.test("U29tZVN0cmluZ09idmlvdXNseU5vdEJhc2U2NEVuY29kZWQ=");   // TRUE
16 голосов
/ 24 октября 2011

Я бы использовал для этого регулярное выражение. Попробуйте это:

/^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/

Пояснение:

^                          # Start of input
([0-9a-zA-Z+/]{4})*        # Groups of 4 valid characters decode
                           # to 24 bits of data for each group
(                          # Either ending with:
    ([0-9a-zA-Z+/]{2}==)   # two valid characters followed by ==
    |                      # , or
    ([0-9a-zA-Z+/]{3}=)    # three valid characters followed by =
)?                         # , or nothing
$                          # End of input
14 голосов
/ 22 октября 2011

Если «valid» означает «содержит только base64-символы», тогда проверьте по [A-Za-z0-9+/=].

Если «valid» означает «легальную» base64-закодированную строку, вам следует проверить = в конце.

Если «действительный» означает, что это что-то разумное после декодирования, то это требует знания предметной области.

2 голосов
/ 07 апреля 2017

Вот как это делается в одной из моих любимых проверочных библиотек:

const notBase64 = /[^A-Z0-9+\/=]/i;

export default function isBase64(str) {
  assertString(str); // remove this line and make sure you pass in a string
  const len = str.length;
  if (!len || len % 4 !== 0 || notBase64.test(str)) {
    return false;
  }
  const firstPaddingChar = str.indexOf('=');
  return firstPaddingChar === -1 ||
    firstPaddingChar === len - 1 ||
    (firstPaddingChar === len - 2 && str[len - 1] === '=');
}

https://github.com/chriso/validator.js/blob/master/src/lib/isBase64.js

2 голосов
/ 20 октября 2015

Этот метод пытается декодировать, затем кодировать и сравнивать с оригиналом. Может также сочетаться с другими ответами для сред, в которых возникают ошибки синтаксического анализа. Также возможно иметь строку, которая выглядит как действительный base64 с точки зрения регулярных выражений, но не является действительным base64.

if(btoa(atob(str))==str){
  //...
}
0 голосов
/ 12 июля 2018

Поскольку здесь представлены в основном две возможности (regex vs try catch), я сравнил производительность обоих: https://jsperf.com/base64-check/

Решение Regex выглядит намного быстрее и явный победитель.Не уверен, что регулярное выражение отлавливает все случаи, но для моих тестов оно работало отлично.

Спасибо @Philzen за регулярное выражение!

ps

В случае, если кто-то заинтересован в поискесамый быстрый способ безопасного декодирования строки base64 (вот как я сюда попал): https://jsperf.com/base64-decoding-check

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