2009-06-23 10 views
34

Pregunta: ¿hay una mejor manera de hacerlo?guid a base64, para URL

VB.Net

Function GuidToBase64(ByVal guid As Guid) As String 
    Return Convert.ToBase64String(guid.ToByteArray).Replace("/", "-").Replace("+", "_").Replace("=", "") 
End Function 

Function Base64ToGuid(ByVal base64 As String) As Guid 
    Dim guid As Guid 
    base64 = base64.Replace("-", "/").Replace("_", "+") & "==" 

    Try 
     guid = New Guid(Convert.FromBase64String(base64)) 
    Catch ex As Exception 
     Throw New Exception("Bad Base64 conversion to GUID", ex) 
    End Try 

    Return guid 
End Function 

C#

public string GuidToBase64(Guid guid) 
{ 
    return Convert.ToBase64String(guid.ToByteArray()).Replace("/", "-").Replace("+", "_").Replace("=", ""); 
} 

public Guid Base64ToGuid(string base64) 
{ 
    Guid guid = default(Guid); 
    base64 = base64.Replace("-", "/").Replace("_", "+") + "=="; 

    try { 
     guid = new Guid(Convert.FromBase64String(base64)); 
    } 
    catch (Exception ex) { 
     throw new Exception("Bad Base64 conversion to GUID", ex); 
    } 

    return guid; 
} 
+0

¿Alguna razón especial para eliminar los caracteres especiales estándar de la codificación Base64? – Hemant

+0

¿Hay alguna razón en particular para codificarlo? Ninguno de los caracteres en un GUID necesita codificación para URL o atributos. – blowdart

+0

@Hemant, porque para URL, + y/y = no funciona bien en un GET, @blowdart, para hacer que la url sea más pequeña – Fredou

Respuesta

9

Entiendo que la razón por la que está recortando == al final es porque puede estar seguro de que para GUID (de 16 bytes), la cadena codificada será siempre final con ==. Por lo tanto, se pueden guardar 2 caracteres en cada conversión.

Además del punto @Skurmedal ya mencionado (debería arrojarse una excepción en caso de cadena no válida como entrada), creo que el código que publicó es lo suficientemente bueno.

+0

No pensé en eso primero, un ahorro de espacio inteligente cuando lo piensas :) – Skurmedel

+0

lo que haría ser el mejor, lidiar con una excepción o consultar la base de datos de todos modos con algo que no existe? ¿Agregaría más código al final ya que verifico si hay al menos una fila en el resultado? – Fredou

+0

El punto es solo acerca de * dónde * quiere poner ese control. Mi experiencia es que las rutinas de la biblioteca de bajo nivel deben ser lo más transparentes posible. Por supuesto, usted es el mejor juez de dónde debe ir el código de comprobación de errores porque * usted * conoce su producto y dónde se encuentra esta biblioteca/código. Fue solo un punto para consideración. – Hemant

3

Si el método no puede convertir la base 64 pasa a ella a un GUID, ¿no debería lanzar una excepción? Los datos pasados ​​al método son claramente erróneos.

+0

No importa, no entendí el código original. – Skurmedel

+0

@Skumedel, Ok :-) – Fredou

+0

Creo que estoy de acuerdo con ustedes, acerca de arrojar una excepción, tiene más sentido – Fredou

11

Un problema con el uso de esta técnica para formatear un GUID para uso en un URL o nombre de archivo es que dos GUID distintas pueden producir dos valores que difieren sólo en caso, por ejemplo:

var b1 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab83c")); 
var b2 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab8a4")); 
Console.WriteLine(b1); // 80XQyRzi0EaXHbkuvCq4PA 
Console.WriteLine(b2); // 80XQyRzi0EaXHbkuvCq4pA 

Desde URLs y los nombres de archivos a menudo se interpretan como insensibles a mayúsculas/minúsculas, esto podría provocar colisiones.