Cómo verificar si una cadena tiene codificación Base64 o no
194
Quiero decodificar una cadena codificada en Base64 y luego almacenarla en mi base de datos. Si la entrada no está codificada en Base64, necesito lanzar un error.
¿Cómo puedo verificar si una cadena está codificada en Base64?
sin especificar a qué lenguaje de programación (y / o) sistema operativo se dirige, esta es una pregunta muy abierta
bcarroll el
55
Todo lo que puede determinar es que la cadena contiene solo caracteres que son válidos para una cadena codificada en base64. Es posible que no sea posible determinar que la cadena es la versión codificada en base64 de algunos datos. por ejemplo, test1234es una cadena codificada en base64 válida, y cuando la decodifique obtendrá algunos bytes. No existe una forma independiente de aplicación de concluir que test1234no sea una cadena codificada en base64.
En la codificación base64, el conjunto de caracteres es [A-Z, a-z, 0-9, and + /]. Si la longitud restante es inferior a 4, la cadena se rellena con '='caracteres.
^([A-Za-z0-9+/]{4})* significa que la cadena comienza con 0 o más grupos base64.
([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$significa que los extremos de cadena en una de tres formas: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}=o [A-Za-z0-9+/]{2}==.
Solo quería verificar, así que por favor ayude con mi pregunta: ¿Cuál es la garantía de que esta expresión regular siempre se refiere solo a una cadena base64? Si hay una cadena que no tiene espacio y es múltiplo de 4 caracteres, ¿se considerará esa cadena como cadena base64?
DShah
3
Entonces es una cadena base64 válida que se puede decodificar. Puede agregar una restricción de longitud mínima; por ejemplo, en lugar de cero o más repeticiones de grupos de cuatro, requieren (por ejemplo) cuatro o más. También depende de tu problema; (? hawaiano) si sus usuarios a menudo entran en una sola palabra en un lenguaje con palabras largas y ASCII puro que es más propenso a errores que si de entrada no base 64 típicamente contiene espacios, puntuacion, etc.
tripleee
62
Esto solo indica que una entrada podría haber sido un valor codificado en b64, pero no indica si la entrada es realmente un valor codificado en b64. En otras palabras, abcdcoincidirá, pero no representa necesariamente el valor codificado de i·una abcdentrada simple
sino Tzury Bar Yochay,
3
Su expresión regular es incorrecta, ya que no coincide con la cadena vacía, con la codificación base64 de datos binarios de longitud cero de acuerdo con RFC 4648.
rojizo
55
@Adomas, "pass" es una cadena base64 perfectamente válida, que decodifica en la secuencia de bytes 0xa5, 0xaby 0x2c. ¿Por qué descartarlo a priori si no tiene más contexto para decidir?
Luis Colorado
50
Si está utilizando Java, en realidad puede usar la biblioteca de códec commons
de la documentación: en isArrayByteBase64(byte[] arrayOctet)desuso. 1.5 Uso isBase64(byte[]), se eliminará en 2.0.
Avinash R
77
También puede usar Base64.isBase64 (String base64) en lugar de convertirlo usted mismo en una matriz de bytes.
Sasa
55
Lamentablemente, según la documentación: commons.apache.org/proper/commons-codec/apidocs/org/apache/… : "Prueba una cadena dada para ver si contiene solo caracteres válidos dentro del alfabeto Base64. Actualmente el método trata los espacios en blanco como válido." Esto significa que este método tiene algunos falsos positivos como "espacios en blanco" o números ("0", "1").
Christian Vielma
para la cadena Base64.isBase64 (contenido)
ema
44
Esta respuesta es incorrecta porque dada stringToBeChecked="some plain text"entonces se establece boolean isBase64=truea pesar de que no es un valor codificado en Base64. Lea la fuente de commons-codec-1.4 Base64.isArrayByteBase64(), solo verifica que cada carácter de la cadena sea válido para ser considerado para la codificación Base64 y permita espacios en blanco.
Brad
49
Bien tu puedes:
Compruebe que la longitud es un múltiplo de 4 caracteres.
Verifique que cada carácter esté en el conjunto AZ, az, 0-9, +, / excepto el relleno al final que es 0, 1 o 2 caracteres '='
Si usted está esperando que va a ser base 64, entonces probablemente puede utilizar cualquier biblioteca está disponible en su plataforma para tratar de decodificar a una matriz de bytes, lanzar una excepción si no es válido para la base 64. Eso depende de la plataforma, por supuesto.
El análisis difiere de la validación al menos por el hecho de que requiere memoria para la matriz de bytes decodificada. Por lo tanto, este no es el enfoque más efectivo en algunos casos.
Victor Yarema el
1
@VictorYarema: sugerí un enfoque de solo validación (puntos de viñeta) y también un enfoque de análisis (después de los puntos de viñeta).
Jon Skeet
16
A partir de Java 8, simplemente puede usar java.util.Base64 para intentar decodificar la cadena:
Sí, es una opción, pero no olvide que la captura es una operación bastante costosa en Java
análisis
2
Ese ya no es el caso. El manejo de excepciones está funcionando bastante bien. Es mejor no olvidar que Java Regex es bastante lento. Quiero decir: ¡REALMENTE LENTO! En realidad, es más rápido decodificar un Base64 y verificar que (no) funcione en lugar de hacer coincidir la Cadena con la expresión regular anterior. Hice una prueba aproximada y la coincidencia de Java Regex es aproximadamente seis veces más lenta (!!) que detectar una eventual excepción en la decodificación.
Sven Döring
Con más pruebas, en realidad es once veces más lento. Es hora de una mejor implementación de Regex en Java. Incluso una verificación Regex con el motor JavaScript de Nashorn en Java es mucho más rápido. Increíble. Además, JavaScript Regex (con Nashorn) es mucho más poderoso.
Sven Döring
3
Con Java 11 (en lugar de Java 8) la comprobación de expresiones regulares es incluso 22 veces más lenta. 🤦 (Porque la decodificación Base64 se hizo más rápida.)
Sven Döring
15
Prueba así 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 esto 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 es este? La pregunta se hizo sin hacer referencia a un idioma
Ozkan
Esto no funcionará. leer los documentos Returns FALSE if input contains character from outside the base64 alphabet.base64_decode
Aley
1
¿Cómo? si la entrada contiene caracteres externos, entonces no es base64, ¿verdad?
Suneel Kumar
7
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');
}
Compruebe SI longitud de la cadena es un múltiplo de 4. Aftwerwards utilizar esta expresión regular para asegurarse de que todos los caracteres de la cadena son base64 caracteres.
\A[a-zA-Z\d\/+]+={,2}\z
Si la biblioteca que usa agrega una nueva línea como una forma de observar los 76 caracteres máximos por regla de línea, reemplácelos con cadenas vacías.
El enlace mencionado muestra 404. Por favor verifique y actualice.
Ankur
Lo siento @AnkurKumar, pero eso es lo que sucede cuando las personas tienen URLs poco interesantes: cambian todo el tiempo. No tengo idea de a dónde se trasladó. Espero que encuentres otros recursos útiles a través de Google
Hay muchas variantes de Base64 , por lo tanto, considere determinar si su cadena se parece a la variante que espera manejar. Como tal, es posible que tenga que ajustar la expresión regular a continuación con respecto a los caracteres de índice y de relleno (es decir +, /, =).
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?
Es imposible verificar si una cadena está codificada en base64 o no. Solo es posible validar si esa cadena es de un formato de cadena codificada en base64, lo que significa que podría ser una cadena producida por la codificación base64 (para verificar que la cadena podría validarse contra una expresión regular o se podría usar una biblioteca, muchas otras respuestas a esta pregunta proporcionan buenas formas de verificar esto, por lo que no entraré en detalles).
Por ejemplo, la cadena flowes una cadena codificada en base64 válida. Pero es imposible saber si es solo una cadena simple, una palabra en inglés flowo si es una cadena codificada en base 64~Z0
esta expresión regular me ayudó a identificar la base64 en mi aplicación en rails, solo tuve un problema, es que reconoce la cadena "errorDescripcion", genero un error, para resolverlo solo validar la longitud de una cadena.
La expresión regular anterior /^.....$/.match(my_string) da un error de formato al decir 'Cierre no
coincidente
Y con 'final prematuro de la clase char: / ^ (([A-Za-z0-9 + /' errores de sintaxis.
james2611nov
No importa lo solucionó agregando \ delante de cada / carácter.
james2611nov
errorDescriptiones una cadena base64 válido, se decodifica en la secuencia binaria de bytes (en hexadecimal): 7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27.
Luis Colorado
Funcionó perfecto para mí para verificar la cadena codificada en base64.
Deepak Lakhara
1
Esto funciona en 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.")
Resumen:IsBase64("string here") devuelve verdadero si string hereestá codificado en Base64, y devuelve falso si string hereNO fue codificado en Base64.
Este fragmento puede ser útil cuando conoce la longitud del contenido original (por ejemplo, una suma de verificación). Comprueba que la forma codificada tiene la longitud correcta.
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() ;
}
Si el RegEx no funciona y conoce el estilo de formato de la cadena original, puede revertir la lógica, regexing para este formato.
Por ejemplo, trabajo con archivos xml codificados en base64 y solo verifico si el archivo contiene un marcado xml válido. Si no es así, puedo suponer que es decodificado en base64. Esto no es muy dinámico, pero funciona bien para mi pequeña aplicación.
Pruebe esto usando una expresión regular mencionada 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");
}
... También podemos hacer una validación simple como, si tiene espacios, no puede 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");
}
si al decodificar obtenemos una cadena con caracteres ASCII, entonces la cadena no fue codificada
(RoR) solución de rubí:
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
es una cadena codificada en base64 válida, y cuando la decodifique obtendrá algunos bytes. No existe una forma independiente de aplicación de concluir quetest1234
no sea una cadena codificada en base64.Respuestas:
Puede usar la siguiente expresión regular para verificar si una cadena está codificada en base64 o no:
En la codificación base64, el conjunto de caracteres es
[A-Z, a-z, 0-9, and + /]
. Si la longitud restante es inferior a 4, la cadena se rellena con'='
caracteres.^([A-Za-z0-9+/]{4})*
significa que la cadena comienza con 0 o más grupos base64.([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$
significa que los extremos de cadena en una de tres formas:[A-Za-z0-9+/]{4}
,[A-Za-z0-9+/]{3}=
o[A-Za-z0-9+/]{2}==
.fuente
abcd
coincidirá, pero no representa necesariamente el valor codificado dei·
unaabcd
entrada simple"pass"
es una cadena base64 perfectamente válida, que decodifica en la secuencia de bytes0xa5
,0xab
y0x2c
. ¿Por qué descartarlo a priori si no tiene más contexto para decidir?Si está utilizando Java, en realidad puede usar la biblioteca de códec commons
fuente
isArrayByteBase64(byte[] arrayOctet)
desuso. 1.5 UsoisBase64(byte[])
, se eliminará en 2.0.stringToBeChecked="some plain text"
entonces se estableceboolean isBase64=true
a pesar de que no es un valor codificado en Base64. Lea la fuente de commons-codec-1.4Base64.isArrayByteBase64()
, solo verifica que cada carácter de la cadena sea válido para ser considerado para la codificación Base64 y permita espacios en blanco.Bien tu puedes:
Si usted está esperando que va a ser base 64, entonces probablemente puede utilizar cualquier biblioteca está disponible en su plataforma para tratar de decodificar a una matriz de bytes, lanzar una excepción si no es válido para la base 64. Eso depende de la plataforma, por supuesto.
fuente
A partir de Java 8, simplemente puede usar java.util.Base64 para intentar decodificar la cadena:
fuente
Prueba así para PHP5
Use esto para PHP7
fuente
Returns FALSE if input contains character from outside the base64 alphabet.
base64_decodefuente
Compruebe SI longitud de la cadena es un múltiplo de 4. Aftwerwards utilizar esta expresión regular para asegurarse de que todos los caracteres de la cadena son base64 caracteres.
\A[a-zA-Z\d\/+]+={,2}\z
Si la biblioteca que usa agrega una nueva línea como una forma de observar los 76 caracteres máximos por regla de línea, reemplácelos con cadenas vacías.
fuente
Hay muchas variantes de Base64 , por lo tanto, considere determinar si su cadena se parece a la variante que espera manejar. Como tal, es posible que tenga que ajustar la expresión regular a continuación con respecto a los caracteres de índice y de relleno (es decir
+
,/
,=
).Uso:
fuente
Prueba esto:
fuente
Es imposible verificar si una cadena está codificada en base64 o no. Solo es posible validar si esa cadena es de un formato de cadena codificada en base64, lo que significa que podría ser una cadena producida por la codificación base64 (para verificar que la cadena podría validarse contra una expresión regular o se podría usar una biblioteca, muchas otras respuestas a esta pregunta proporcionan buenas formas de verificar esto, por lo que no entraré en detalles).
Por ejemplo, la cadena
flow
es una cadena codificada en base64 válida. Pero es imposible saber si es solo una cadena simple, una palabra en inglésflow
o si es una cadena codificada en base 64~Z0
fuente
esta expresión regular me ayudó a identificar la base64 en mi aplicación en rails, solo tuve un problema, es que reconoce la cadena "errorDescripcion", genero un error, para resolverlo solo validar la longitud de una cadena.
fuente
errorDescription
es una cadena base64 válido, se decodifica en la secuencia binaria de bytes (en hexadecimal):7a ba e8 ac 37 ac 72 b8 a9 b6 2a 27
.Esto funciona en Python:
Resumen:
IsBase64("string here")
devuelve verdadero sistring here
está codificado en Base64, y devuelve falso sistring here
NO fue codificado en Base64.fuente
C # Esto está funcionando muy bien:
fuente
Console.WriteLine("test".IsBase64()); // true
No hay forma de codificar una cadena distinta y una base64, excepto que la cadena en su sistema tiene alguna limitación o identificación específica.
fuente
Este fragmento puede ser útil cuando conoce la longitud del contenido original (por ejemplo, una suma de verificación). Comprueba que la forma codificada tiene la longitud correcta.
fuente
Si el RegEx no funciona y conoce el estilo de formato de la cadena original, puede revertir la lógica, regexing para este formato.
Por ejemplo, trabajo con archivos xml codificados en base64 y solo verifico si el archivo contiene un marcado xml válido. Si no es así, puedo suponer que es decodificado en base64. Esto no es muy dinámico, pero funciona bien para mi pequeña aplicación.
fuente
Esto funciona en Python:
fuente
Pruebe esto usando una expresión regular mencionada anteriormente:
... También podemos hacer una validación simple como, si tiene espacios, no puede ser Base64:
fuente
(RoR) solución de rubí:
fuente
Intento usar esto, sí, este está funcionando
pero agregué la condición para verificar que al menos el final del carácter sea =
fuente
=
? ¿Qué especificaciónBase64
utiliza? ¿Quéend of the character
significa y cómo no negativolastIndexOf()
verifica eso?