¿Codificación Base64 segura para nombres de archivos?

¿Es seguro usar la encoding Base64 para los nombres de archivo en sistemas Windows y Linux? De mi investigación encontré que reemplazar todos / caracteres del resultado con - o _ debería resolver cualquier problema.

¿Alguien puede proporcionar más detalles sobre esto?

Actualmente en Java estoy usando el siguiente trozo de código:

 MessageDigest md5Digest = MessageDigest.getInstance("MD5"); md5Digest.reset(); md5Digest.update(plainText.getBytes()); byte[] digest = md5Digest.digest(); BASE64Encoder encoder = new BASE64Encoder(); hash = encoder.encode(digest); hash.replace('/','_'); 

La Base64 modificada (cuando / , = y + se reemplazan) es segura para crear nombres, pero no garantiza la transformación inversa debido a la falta de sensibilidad de muchos sistemas de archivos y URL.

Base64 distingue entre mayúsculas y minúsculas, por lo que no garantiza el mapeo 1 a 1 en los casos de sistemas de archivos que no distinguen entre mayúsculas y minúsculas (todos los sistemas de archivos de Windows, ignorando los casos del subsistema POSIX). La mayoría de las URL también distinguen entre mayúsculas y minúsculas, lo que evita el mapeo 1-a-1.

Yo usaría Base32 en este caso: obtendrá nombres un poco más largos, pero los valores codificados en Base32 son 100% seguros para el uso de archivos / uri sin reemplazar ningún carácter y garantizan el mapeo 1-a-1 incluso en casos de entornos insensibles (FAT / Win32 NTFS acceso).

Desafortunadamente, generalmente no hay soporte incorporado para esta encoding en los marcos. Por otro lado, el código es relativamente simple para escribirlo o encontrarlo en línea.

http://en.wikipedia.org/wiki/Base32 .

No estoy seguro de para qué está utilizando la encoding, pero considere el porcentaje de encoding de nombres de archivos.

  • Funciona en todos los sistemas de archivos.
  • Mantiene los nombres de los archivos legibles, siempre y cuando estén dentro del rango ASCII

RFC 3548 sugiere no solo reemplazar el carácter / . La URL y el nombre seguro del alfabeto sustituyen a:

  • El 63: nd / carácter con el guión bajo _
  • el 62: nd + carácter con el signo menos - .

Pero quizás sea mejor que uses una cadena HEX. Ha pasado un tiempo, cuando almacené un valor hash en un nombre de archivo. Comencé con el uso de Base64 String pero cambié a una Hex-String. No recuerdo por qué cambié, tal vez porque Windows no hace ninguna diferencia entre ‘a’ y ‘A’ como dijo AndiDog.

One-liner para C #:

 String filename = Convert.ToBase64String(new SHA256Managed().ComputeHash(Encoding.UTF8.GetBytes("UTF-8 string with snowmen"))).Replace("+", "_").Replace("/", "-").Replace("=",""); 

Necesita lo siguiente al principio del archivo:

 using System.Security.Cryptography using System.Text 

Un nombre de archivo creado por Base64 solo es seguro si usa un carácter diferente de /, lo que hace, ya que NTFS no permite que ese carácter se use en los nombres de archivo. Siempre y cuando hagas eso, casi todos los sistemas de archivos de uso común de uso común estarán bien.

Sin embargo, si el sistema de archivos no distingue entre mayúsculas y minúsculas , como es el caso en Windows, puede obtener colisiones porque el alfabeto Base64 contiene mayúsculas y minúsculas.

Es posible que desee considerar el uso de la representación hexadecimal de su hash MD5 en su lugar, ya que esta es una forma bastante estándar de representar a esos como una cadena.

Por lo general, los hashes MD5 (los hashes en general) se representan como cadenas hexadecimales en lugar de Base64, que solo contienen [a-f0-9]. Esos nombres serían compatibles con todos los sistemas de archivos.

Si realmente desea utilizar Base64, su solución (que reemplaza las barras) no funcionará correctamente, ya que los sistemas de archivos de Windows no hacen una diferencia entre ‘A’ y ‘a’. Tal vez quieras usar Base32 en su lugar? Pero tenga en cuenta que Base32 hace 8 bits de 4, por lo que será más fácil simplemente tomar la representación hexadecimal.

En general, los siguientes caracteres no están permitidos en Windows y / o Linux: \ /: *? “<> |