Pregunta: ¿hay una manera mejor de hacer esto?

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;
}
  • Alguna razón en especial de eliminación estándar de los caracteres especiales de la codificación Base64?
  • Hay una razón en particular que usted necesita para codificar? Ninguno de los personajes en un GUID necesidad de codificación de Url o atributos.
  • porque para la URL, + y / y = no funciona bien en un GET, @blowdart, para hacer las url más pequeños
  • Supongo que @Fredou quiere cadena resultante tan corto como sea posible, es por eso que él es la codificación de los mismos.
  • Base64 hace una cadena de 33% más GRANDE, ni más pequeño
  • Codificado en Base64 de la cadena es menor que la de hex de la codificación, que es el formato predeterminado cuando se utiliza .ToString (). Offcourse nadie desea transmitir raw (no imprimible bytes) directamente.
  • cómo «37945704-cf86-4b2e-a4b5-0db0204902c8» es mayor que «BFeUN4bPLkuktQ2wIEkCyA»
  • me puedes dar 1 guid que habría «=» cuando se convierte en base64?
  • Me gustaría considerar la posibilidad de no hacer el .reemplazar de codificación de URL, o proporcionar un seperate método para que. Esto permitiría una separación de preocupaciones donde los usuarios de la API podría elegir si querían real de codificación de base64 o la URL amigable de codificación de base64, dependiendo de lo que desean lograr. Entiendo que su objetivo era para uso de la dirección URL, pero todo excepto la URL de la etapa de codificación podría ser utilizado para aquellos que quieren un corto base64 pero no lo utiliza en una dirección URL.
  • Ejecutar «aaaaaaaaaaaaaaaaaaaaaa» a través de Base64ToGuid(), luego tomar el Guid devuelto y ejecutarlo a través de GuidToBase64() y get «aaaaaaaaaaaaaaaaaaaaaQ». Un montón de otros ejemplos como este.
  • lo siento por la respuesta tardía. su derecho de que la codificación en base64 dar un resultado diferente pero ambos dan el mismo Guid.
  • Yo recomendaría cambiar los sustitutos, es decir, en lugar de .Replace("+", "_") y viceversa y Replace("/", "-") y viceversa, utilice .Replace("+", "-") y viceversa y Replace("/", "_") y viceversa. Esto haría que la codificación compatible con RFC 4648 base64url (ver tools.ietf.org/html/rfc4648#section-5)

InformationsquelleAutor Fredou | 2009-06-23

4 Comentarios

  1. 13

    Entiendo que la razón por la que se recorte == en la final es porque usted puede estar seguro de que para GUID (de 16 bytes), cadena codificada que se siempre final con ==. Así que 2 personajes pueden ser guardados en cada conversión.

    Al lado del punto @Skurmedal ya mencionados (debe lanzar una excepción en el caso de cadena no válida como entrada), creo que el código que has publicado es sólo lo suficientemente bueno.

    • No había pensado que la primera cosa, un gran ahorro de espacio cuando se piensa en ello 🙂
    • lo que sería mejor, tratar con una excepción o consultar la base de datos de todos modos con algo que no existe? sería agregar más código en la final, ya que compruebe si hay al menos una fila en el resultado?
    • El punto es sólo acerca de cuando quiero poner el cheque. Mi experiencia es que el bajo nivel rutinas de la biblioteca debe ser tan transparente como sea posible. Offcourse aquí usted es el mejor juez de donde el error de comprobación de código debe ir, porque conocer su producto y donde esta librería/código de stands. Era sólo un punto para su consideración.
    • Así, si se trata de una excepción por lo menos sabes que algo ha ido mal. Es posible que no importa ahora, pero en el futuro tal vez. No conozco su programa de buena enoug 🙂 creo que la consulta de la base de datos para cosas que (en teoría) sabemos que no existe es el menos favorable solución.
    • Creo que estoy de acuerdo con ustedes, se trata de lanzar una excepción, tendría más sentido
    • Se debe colocar en base64.Reemplazar(«-«, «/»)… dentro de la prueba de bloque para evitar un uncaught NullReferenceException+ si base64 == null

  2. 25

    Usted puede ser que desee comprobar hacia fuera este sitio: http://prettycode.org/2009/11/12/short-guid/

    Se ve muy cerca de lo que estás haciendo.

    public class ShortGuid
    {
    private readonly Guid guid;
    private readonly string value;
    ///<summary>Create a 22-character case-sensitive short GUID.</summary>
    public ShortGuid(Guid guid)
    {
    if (guid == null)
    {
    throw new ArgumentNullException("guid");
    }
    this.guid = guid;
    this.value = Convert.ToBase64String(guid.ToByteArray())
    .Substring(0, 22)
    .Replace("/", "_")
    .Replace("+", "-");
    }
    ///<summary>Get the short GUID as a string.</summary>
    public override string ToString()
    {
    return this.value;
    }
    ///<summary>Get the Guid object from which the short GUID was created.</summary>
    public Guid ToGuid()
    {
    return this.guid;
    }
    ///<summary>Get a short GUID as a Guid object.</summary>
    ///<exception cref="System.ArgumentNullException"></exception>
    ///<exception cref="System.FormatException"></exception>
    public static ShortGuid Parse(string shortGuid)
    {
    if (shortGuid == null)
    {
    throw new ArgumentNullException("shortGuid");
    }
    else if (shortGuid.Length != 22)
    {
    throw new FormatException("Input string was not in a correct format.");
    }
    return new ShortGuid(new Guid(Convert.FromBase64String
    (shortGuid.Replace("_", "/").Replace("-", "+") + "==")));
    }
    public static implicit operator String(ShortGuid guid)
    {
    return guid.ToString();
    }
    public static implicit operator Guid(ShortGuid shortGuid)
    {
    return shortGuid.guid;
    }
    }
  3. 17

    Un problema con el uso de esta técnica para dar formato a un GUID para el uso en una dirección o nombre de archivo es que dos distintas Guid puede producir dos valores que difieren sólo en el 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 las Url se interpretan a veces como mayúsculas y minúsculas, y en Windows el archivo de rutas y nombres de archivo son insensibles a mayúsculas /minúsculas. esto podría llevar a las colisiones.

    • Esta es incorrecto para las direcciones Url. Sólo el esquema y el host debe tener en cuenta las mayúsculas y minúsculas, como por RFC 3986. Consulta, fragmento, e incluso la ruta de acceso debe tener en cuenta las mayúsculas y minúsculas. Por supuesto, todo depende de tu código/servidor de la aplicación para que se adhieran a este.
    • buen punto re: direcciones Url, pero yo estaba pensando más en específico a la aplicación de la tramitación de un URL como http://.../user/{id}, donde {id} podría ser un guid aleatorio-como identificación para evitar la OWASP la Fuerza Bruta de Predicción de la Ubicación de Recurso de la vulnerabilidad, y el identificador puede ser consultado en caso insensibles a la base de datos.
  4. 3

    Si el método no se puede convertir el Base64 pasado a un GUID, en caso de no lanzar una excepción? Los datos que se pasan al método es claramente erronous.

    • No importa, yo missunderstood el código original.
    • Ok 🙂
    • Creo que estoy de acuerdo con ustedes, se trata de lanzar una excepción, tendría más sentido

Dejar respuesta

Please enter your comment!
Please enter your name here