2009-06-23 21 views
34

Pytanie: czy istnieje lepszy sposób na zrobienie tego?przewodnik do base64, adres 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

Czy istnieje jakaś specjalna przyczyna usunięcia standardowych znaków specjalnych z kodowania Base64? – Hemant

+0

Czy istnieje jakiś szczególny powód, dla którego należy go zakodować? Żaden z znaków w GUID nie wymaga kodowania adresów URL ani atrybutów. – blowdart

+0

@Dziecko, ponieważ dla adresu URL, + i/i = nie działa dobrze w GET, @blowdart, aby adres URL był mniejszy – Fredou

Odpowiedz

9

Rozumiem, że powodem, dla którego przycinasz == na końcu, jest to, że możesz być pewien, że dla GUID (16 bajtów), zakodowany ciąg będzie zawsze kończy się na ==. W każdej konwersji można zapisać 2 znaki.

Oprócz wspomnianego już @Skurmedal (powinien podać wyjątek w przypadku niepoprawnego łańcucha jako danych wejściowych), myślę, że napisany przez Ciebie kod jest wystarczająco dobry.

+0

Nie pomyślałem o tej pierwszej rzeczy, sprytny oszczędność miejsca, kiedy o tym pomyślisz :) – Skurmedel

+0

co by było być najlepszym, zajmować się wyjątkiem lub zapytać w bazie danych z czymś, co nie istnieje? czy w końcu doda więcej kodu, ponieważ sprawdzam, czy w wyniku jest co najmniej jeden wiersz? – Fredou

+0

Punkt dotyczy tylko * miejsca, w którym * chcesz umieścić czek. Z mojego doświadczenia wynika, że ​​procedury biblioteczne niskiego poziomu powinny być tak przejrzyste, jak to tylko możliwe. Oczywiście tutaj jesteś najlepszym sędzią, gdzie powinien się znajdować kod sprawdzania błędów, ponieważ * znasz * swój produkt i gdzie znajduje się ta biblioteka/kod. To był tylko punkt do rozważenia. – Hemant

3

Jeśli metoda nie może przekonwertować Base64 przeszedł do niego do GUID, nie należy rzucać wyjątek? Dane przekazane do metody są wyraźnie błędne.

+0

Nieważne, nie widziałem oryginalnego kodu. – Skurmedel

+0

@Skumedel, Ok :-) – Fredou

+0

Myślę, że zgadzam się z wami, o wyrzuceniu wyjątku, to ma więcej sensu – Fredou

11

Jednym z problemów przy użyciu tej techniki formatowania GUID do użycia w adresie URL lub nazwy pliku jest to, że dwa odrębne GUID może produkować dwie wartości, które różnią się jedynie w przypadku, np

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 

Od URL nazwy plików są często interpretowane jako nieistotne dla przypadku, co może doprowadzić do kolizji.