Como verificar se uma string é codificada em Base64 ou não
194
Quero decodificar uma string codificada em Base64 e armazená-la no meu banco de dados. Se a entrada não estiver codificada em Base64, preciso gerar um erro.
Como posso verificar se uma string é codificada em Base64?
sem especificar qual linguagem de programação (e / ou) Sistema Operacional lhe são dirigidas, esta é uma pergunta muito aberta
bcarroll
5
Tudo o que você pode determinar é que a sequência contém apenas caracteres válidos para uma sequência codificada em base64. Talvez não seja possível determinar se a sequência é a versão codificada em base64 de alguns dados. por exemplo, test1234é uma string codificada em base64 válida e, quando você a decodificar, receberá alguns bytes. Não há maneira independente de concluir a aplicação que test1234não seja uma sequência codificada em base64.
Na codificação base64, o conjunto de caracteres é [A-Z, a-z, 0-9, and + /]. Se o comprimento restante for menor que 4, a sequência será preenchida com '='caracteres.
^([A-Za-z0-9+/]{4})* significa que a sequência começa com 0 ou mais grupos base64.
([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$significa que as extremidades da corda em uma de três formas: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=ou [A-Za-z0-9+/]{2}==.
Só queria verificar, por favor ajude com a minha pergunta: Qual é a garantia de que esse regex sempre se refere apenas à string base64? Se houver qualquer sequência que não tenha espaço e for múltiplo de 4 caracteres, essa sequência será considerada como sequência base64 ????
DShah 01/10/12
3
Então é uma string base64 válida que pode ser decodificada. Você pode adicionar uma restrição de comprimento mínimo; por exemplo, em vez de zero ou mais repetições de grupos de quatro, exija (digamos) quatro ou mais. Depende do seu problema também; (? havaiana) se os usuários muitas vezes entra uma única palavra em um idioma com palavras longas e ASCII puro que é mais propenso a erros do que se a entrada não-base64 normalmente contém espaços, pontuação, etc.
tripleee
62
Isso indica apenas que uma entrada poderia ter sido um valor codificado em b64, mas não informa se a entrada é realmente um valor codificado em b64. Em outras palavras, abcdirá corresponder, mas não é necessariamente representam o valor codificado de i·sim apenas uma planície abcdde entrada
Tzury Bar Yochay
3
Seu regexp é incorrecta, uma vez que não coincide com a cadeia vazia, com é a codificação base64 de dados binários de comprimento zero de acordo com RFC 4648.
avermelhada
5
@Adomas, "pass" é uma cadeia de base64 perfeitamente válido, que decodifica os dados para a sequência de bytes 0xa5, 0xabe 0x2c. Por que descartá-lo a priori , se você não tem mais contexto para decidir?
Luis Colorado
50
Se você estiver usando Java, poderá usar a biblioteca commons-codec
da documentação: isArrayByteBase64(byte[] arrayOctet)Descontinuado. 1.5 Use isBase64(byte[]), será removido no 2.0.
Avinash R
7
Você também pode usar Base64.isBase64 (String base64) em vez de convertê-lo em matriz de bytes.
Sasa
5
Infelizmente, com base na documentação: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "Testa uma determinada String para ver se ela contém apenas caracteres válidos no alfabeto Base64. Atualmente, o método trata o espaço em branco como válido." Isso significa que esse método possui alguns falsos positivos, como "espaço em branco" ou números ("0", "1").
Christian Vielma
para string Base64.isBase64 (content)
ema
3
Essa resposta está errada porque, em stringToBeChecked="some plain text"seguida, é definida, boolean isBase64=truemesmo que não seja um valor codificado em Base64. Leia a fonte do commons-codec-1.4 Base64.isArrayByteBase64(), apenas verifica se cada caractere na sequência é válido para ser considerado na codificação Base64 e permite espaço em branco.
Brad
49
Bem, você pode:
Verifique se o comprimento é múltiplo de 4 caracteres
Verifique se todos os caracteres estão no conjunto AZ, az, 0-9, +, /, exceto pelo preenchimento no final, que é 0, 1 ou 2 '=' caracteres
Se você está esperando que vai ser base64, então provavelmente você pode simplesmente usar qualquer biblioteca está disponível em sua plataforma para tentar decodificá-lo para um array de bytes, lançando uma exceção se não é de base válido 64. Isso depende de sua plataforma, claro.
A análise difere da validação pelo menos pelo fato de exigir memória para uma matriz de bytes decodificada. Portanto, essa não é a abordagem mais eficaz em alguns casos.
Victor Yarema 22/09/19
1
@ VictorYarema: sugeri uma abordagem somente de validação (pontos de bala) e também uma abordagem de análise (após os pontos de bala).
Jon Skeet
16
No Java 8, você pode simplesmente usar java.util.Base64 para tentar decodificar a sequência:
sim, é uma opção, mas não se esqueça que captura é uma operação muito caro em Java
Panser
2
Esse não é mais o caso. O tratamento de exceções está executando muito bem. É melhor não esquecer que o Java Regex é bem lento. Quero dizer: REALMENTE LENTO! Na verdade, é mais rápido decodificar um Base64 e verificar se ele está (não) funcionando em vez de corresponder a String ao Regex acima. Fiz um teste aproximado e a correspondência do Java Regex é cerca de seis vezes mais lenta (!!) do que a captura de uma exceção eventual na decodificação.
Sven Döring
Com mais testes, é onze vezes mais lento. Está na hora de uma melhor implementação do Regex em Java. Mesmo uma verificação Regex com o mecanismo JavaScript Nashorn em Java é muito mais rápida. Inacreditável. Além disso, o JavaScript Regex (com Nashorn) é muito mais poderoso.
Sven Döring
3
No Java 11 (em vez do Java 8), a verificação Regex é 22 vezes mais lenta. 🤦 (Porque a decodificação Base64 ficou mais rápido.)
Sven Döring
15
Tente assim para PHP5
//where $json is some data that can be base64 encoded
$json=some_data;
//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{
echo "base64 encoded";
}
else
{
echo "not base64 encoded";
}
Use isso para PHP7
//$string parameter can be base64 encoded or not
function is_base64_encoded($string){
//this will check if $string is base64 encoded and return true, if it is.
if (base64_decode($string, true) !== false){
return true;
}else{
return false;
}
}
Que idioma é esse? A pergunta foi feita sem se referir a um idioma
Ozkan 27/11
isso não vai funcionar. leia os documentos Returns FALSE if input contains character from outside the base64 alphabet.base64_decode
Aley
1
Quão? se a entrada contém caracteres externos, não é base64, certo?
Suneel Kumar 01/02
6
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string
if (isBase64Valid) {
// true if base64 formate
console.log('It is base64');
} else {
// false if not in base64 formate
console.log('it is not in base64');
}
Verifique se o comprimento da sequência é múltiplo de 4. Posteriormente, use esse regex para garantir que todos os caracteres na sequência sejam caracteres base64.
\A[a-zA-Z\d\/+]+={,2}\z
Se a biblioteca que você usa adicionar uma nova linha como uma maneira de observar a regra de 76 caracteres máximos por linha, substitua-as por cadeias vazias.
O link mencionado mostra 404. Por favor, verifique e atualize.
Ankur
Desculpe @AnkurKumar, mas é isso que acontece quando as pessoas têm URLs não legais: elas mudam o tempo todo. Não faço ideia para onde foi movido. Espero que você encontre outros recursos úteis pelo Google
Existem muitas variantes do Base64 , portanto, considere apenas determinar se sua sequência se assemelha à variação que você espera manipular. Como tal, pode ser necessário ajustar a regex abaixo com respeito aos caracteres de índice e enchimento (isto é +, /, =).
class String
def resembles_base64?
self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
end
end
Uso:
raise 'the string does not resemble Base64' unless my_string.resembles_base64?
É impossível verificar se uma sequência é codificada em base64 ou não. Só é possível validar se essa sequência possui um formato de sequência codificada em base64, o que significa que poderia ser uma sequência produzida pela codificação base64 (para verificar se a sequência pode ser validada em um regexp ou se uma biblioteca pode ser usada, muitos outras respostas a essa pergunta fornecem boas maneiras de verificar isso, para não entrar em detalhes).
Por exemplo, string flowé uma string codificada em base64 válida. Mas é impossível saber se é apenas uma sequência simples, uma palavra em inglês flowou se é uma sequência codificada de base 64~Z0
essa expressão regular me ajudou a identificar a base64 na minha aplicação em trilhos, só tive um problema, é que reconhece a string "errorDescripcion", gere um erro, para resolvê-la apenas valida o comprimento de uma string.
O regex acima /^.....$/.match(my_string) fornece um erro de formatação dizendo 'Fechamento sem correspondência)'
james2611nov
E com 'final prematuro da classe char: / ^ (([A-Za-z0-9 + /' erros de sintaxe.
james2611nov
Não importa, conserte-o adicionando \ na frente de cada caractere /.
James2611nov 17/05/19
errorDescriptioné uma cadeia de base64 válido, descodifica-o na sequência de binário de bytes (em hexadecimal): 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
Luis Colorado
Funcionou perfeito para eu verificar a string codificada em base64.
Deepak Lakhara,
1
Isso funciona em Python:
import base64
def IsBase64(str):
try:
base64.b64decode(str)
return True
except Exception as e:
return False
if IsBase64("ABC"):
print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
print("ABC is NOT Base64-encoded.")
if IsBase64("QUJD"):
print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
print("QUJD is NOT Base64-encoded.")
Resumo:IsBase64("string here") retorna true se string herefor codificado em Base64 e retorna false se string herenão foi codificado em Base64.
Este trecho pode ser útil quando você souber o tamanho do conteúdo original (por exemplo, uma soma de verificação). Ele verifica se o formulário codificado tem o comprimento correto.
public static boolean isValidBase64( final int initialLength, final String string ) {
final int padding ;
final String regexEnd ;
switch( ( initialLength ) % 3 ) {
case 1 :
padding = 2 ;
regexEnd = "==" ;
break ;
case 2 :
padding = 1 ;
regexEnd = "=" ;
break ;
default :
padding = 0 ;
regexEnd = "" ;
}
final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
return Pattern.compile( regex ).matcher( string ).matches() ;
}
Se o RegEx não funcionar e você souber o estilo de formato da sequência original, poderá inverter a lógica regexando para esse formato.
Por exemplo, eu trabalho com arquivos xml codificados em base64 e apenas verifico se o arquivo contém uma marcação xml válida. Se não, posso assumir, que é decodificado em base64. Isso não é muito dinâmico, mas funciona bem para meu pequeno aplicativo.
Tente isso usando um regex mencionado anteriormente:
String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
System.out.println("it's a Base64");
}
... Também podemos fazer uma validação simples como, se tiver espaços, não poderá ser Base64:
String myString = "Hello World";
if(myString.contains(" ")){
System.out.println("Not B64");
}else{
System.out.println("Could be B64 encoded, since it has no spaces");
}
se ao decodificar obtemos uma sequência com caracteres ASCII, a sequência não foi codificada
Solução de rubi (RoR):
def encoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end
def decoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end
test1234
é uma string codificada em base64 válida e, quando você a decodificar, receberá alguns bytes. Não há maneira independente de concluir a aplicação quetest1234
não seja uma sequência codificada em base64.Respostas:
Você pode usar a seguinte expressão regular para verificar se uma sequência está codificada em base64 ou não:
Na codificação base64, o conjunto de caracteres é
[A-Z, a-z, 0-9, and + /]
. Se o comprimento restante for menor que 4, a sequência será preenchida com'='
caracteres.^([A-Za-z0-9+/]{4})*
significa que a sequência começa com 0 ou mais grupos base64.([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$
significa que as extremidades da corda em uma de três formas:[A-Za-z0-9+/]{4}
,[A-Za-z0-9+/]{3}=
ou[A-Za-z0-9+/]{2}==
.fonte
abcd
irá corresponder, mas não é necessariamente representam o valor codificado dei·
sim apenas uma planícieabcd
de entrada"pass"
é uma cadeia de base64 perfeitamente válido, que decodifica os dados para a sequência de bytes0xa5
,0xab
e0x2c
. Por que descartá-lo a priori , se você não tem mais contexto para decidir?Se você estiver usando Java, poderá usar a biblioteca commons-codec
fonte
isArrayByteBase64(byte[] arrayOctet)
Descontinuado. 1.5 UseisBase64(byte[])
, será removido no 2.0.stringToBeChecked="some plain text"
seguida, é definida,boolean isBase64=true
mesmo que não seja um valor codificado em Base64. Leia a fonte do commons-codec-1.4Base64.isArrayByteBase64()
, apenas verifica se cada caractere na sequência é válido para ser considerado na codificação Base64 e permite espaço em branco.Bem, você pode:
Se você está esperando que vai ser base64, então provavelmente você pode simplesmente usar qualquer biblioteca está disponível em sua plataforma para tentar decodificá-lo para um array de bytes, lançando uma exceção se não é de base válido 64. Isso depende de sua plataforma, claro.
fonte
No Java 8, você pode simplesmente usar java.util.Base64 para tentar decodificar a sequência:
fonte
Tente assim para PHP5
Use isso para PHP7
fonte
Returns FALSE if input contains character from outside the base64 alphabet.
base64_decodefonte
Verifique se o comprimento da sequência é múltiplo de 4. Posteriormente, use esse regex para garantir que todos os caracteres na sequência sejam caracteres base64.
\A[a-zA-Z\d\/+]+={,2}\z
Se a biblioteca que você usa adicionar uma nova linha como uma maneira de observar a regra de 76 caracteres máximos por linha, substitua-as por cadeias vazias.
fonte
Existem muitas variantes do Base64 , portanto, considere apenas determinar se sua sequência se assemelha à variação que você espera manipular. Como tal, pode ser necessário ajustar a regex abaixo com respeito aos caracteres de índice e enchimento (isto é
+
,/
,=
).Uso:
fonte
Tente o seguinte:
fonte
É impossível verificar se uma sequência é codificada em base64 ou não. Só é possível validar se essa sequência possui um formato de sequência codificada em base64, o que significa que poderia ser uma sequência produzida pela codificação base64 (para verificar se a sequência pode ser validada em um regexp ou se uma biblioteca pode ser usada, muitos outras respostas a essa pergunta fornecem boas maneiras de verificar isso, para não entrar em detalhes).
Por exemplo, string
flow
é uma string codificada em base64 válida. Mas é impossível saber se é apenas uma sequência simples, uma palavra em inglêsflow
ou se é uma sequência codificada de base 64~Z0
fonte
essa expressão regular me ajudou a identificar a base64 na minha aplicação em trilhos, só tive um problema, é que reconhece a string "errorDescripcion", gere um erro, para resolvê-la apenas valida o comprimento de uma string.
fonte
errorDescription
é uma cadeia de base64 válido, descodifica-o na sequência de binário de bytes (em hexadecimal):7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27
.Isso funciona em Python:
Resumo:
IsBase64("string here")
retorna true sestring here
for codificado em Base64 e retorna false sestring here
não foi codificado em Base64.fonte
C # Isso está executando muito bem:
fonte
Console.WriteLine("test".IsBase64()); // true
Não há como distinguir a string e a base64, exceto que a string no seu sistema possui alguma limitação ou identificação específica.
fonte
Este trecho pode ser útil quando você souber o tamanho do conteúdo original (por exemplo, uma soma de verificação). Ele verifica se o formulário codificado tem o comprimento correto.
fonte
Se o RegEx não funcionar e você souber o estilo de formato da sequência original, poderá inverter a lógica regexando para esse formato.
Por exemplo, eu trabalho com arquivos xml codificados em base64 e apenas verifico se o arquivo contém uma marcação xml válida. Se não, posso assumir, que é decodificado em base64. Isso não é muito dinâmico, mas funciona bem para meu pequeno aplicativo.
fonte
Isso funciona em Python:
fonte
Tente isso usando um regex mencionado anteriormente:
... Também podemos fazer uma validação simples como, se tiver espaços, não poderá ser Base64:
fonte
Solução de rubi (RoR):
fonte
Eu tento usar isso, sim este está funcionando
mas eu adicionei a condição de verificar pelo menos o final do caractere é =
fonte
=
: Qual especificaçãoBase64
você está usando? O queend of the character
significa e como não negativolastIndexOf()
verifica isso?