Değiştirilmiş bir base64 URL'sinin kodunu çözmek / kodlamak için kod


113

Veriyi bir URL'ye koymak için base64 kodlamak ve ardından HttpHandler'ım içinde kodunu çözmek istiyorum.

Base64 Kodlamasının UriTemplate eşleşmemi bozacak bir '/' karakterine izin verdiğini buldum . Sonra wikipedia'dan "URL için değiştirilmiş Base64" kavramı olduğunu buldum:

URL varyantı için değiştirilmiş bir Base64 mevcuttur, burada hiçbir '=' dolgusu kullanılmaz ve standart Base64'ün '+' ve '/' karakterleri sırasıyla '-' ve '_' ile değiştirilir, böylece URL kodlayıcılar / kod çözücüler kullanılır artık gerekli değildir ve kodlanmış değerin uzunluğu üzerinde hiçbir etkisi yoktur, aynı kodlanmış formu ilişkisel veritabanlarında, web formlarında ve genel olarak nesne tanımlayıcılarında kullanım için bozulmadan bırakır.

.NET kullanarak Geçerli kodumu temel base64 kodlama ve kod çözme işleminden "URL için değiştirilmiş base64" yöntemini kullanmaya değiştirmek istiyorum. Bunu kimse yaptı mı?

Çözmek için şunun gibi bir şeyle başladığını biliyorum

string base64EncodedText = base64UrlEncodedText.Replace('-', '+').Replace('_', '/');

// Append '=' char(s) if necessary - how best to do this?

// My normal base64 decoding now uses encodedText

Ancak, biraz daha karmaşık görünen sonuna bir veya iki '=' karakter eklemem gerekiyor.

Kodlama mantığım biraz daha basit olmalı:

// Perform normal base64 encoding
byte[] encodedBytes = Encoding.UTF8.GetBytes(unencodedText);
string base64EncodedText = Convert.ToBase64String(encodedBytes);

// Apply URL variant
string base64UrlEncodedText = base64EncodedText.Replace("=", String.Empty).Replace('+', '-').Replace('/', '_');

URL StackOverflow girişi için Base64 için Guid'i gördüm , ancak bunun bilinen bir uzunluğu var ve bu nedenle sonunda gereken eşit işaretlerin sayısını kodlayabilirler.


@Kirk: Cevabımı test edilmiş matematikle ayarlayın.
AnthonyWJones

Yanıtlar:


69

Bu, onu doğru şekilde doldurmalıdır: -

 base64 = base64.PadRight(base64.Length + (4 - base64.Length % 4) % 4, '=');

11
Bah, beni yendin. Sadece gönderimi sileceğim çünkü neredeyse seni kopyalamışım gibi görünüyor :)
AaronLS

3
Bu üç '=' karaktere kadar eklenmeyecek mi? Görünüşe göre bunlardan sadece 0, 1 veya 2 olacak.
Kirk Liemohn

1
@Kirk: 3 karakter eklerse, base64 dizesi zaten bozuktur. Sanırım dizeyi doğrulamak iyi bir fikir olur, yalnızca beklenen karakterleri ve Uzunluk% 4! = 3'ü içermelidir.
AnthonyWJones

Hmmm. Bunu denerken hile yapmıyor. Hala cevaplar arıyorum. Eşit işaretlerin sayısı doğru bir şekilde değişmiyor.
Kirk Liemohn

2
@AnthonyWJones 'sadece beklenen karakterleri ve Uzunluk% 4! = 1 ' içermelidir , değil mi?
2013

173

Ayrıca URL güvenli Base64 kodlama ve kod çözme işlemlerini gerçekleştiren UrlTokenEncode ve UrlTokenDecode yöntemleriyle HttpServerUtility sınıfını da kontrol edin .

Not 1: Sonuç geçerli bir Base64 dizesi değil. URL için bazı güvenli olmayan karakterler değiştirildi.

Not 2: Sonuç, RFC4648'deki base64url algoritmasından farklıdır.

///<summary>
/// Base 64 Encoding with URL and Filename Safe Alphabet using UTF-8 character set.
///</summary>
///<param name="str">The origianl string</param>
///<returns>The Base64 encoded string</returns>
public static string Base64ForUrlEncode(string str)
{
    byte[] encbuff = Encoding.UTF8.GetBytes(str);
    return HttpServerUtility.UrlTokenEncode(encbuff);
}
///<summary>
/// Decode Base64 encoded string with URL and Filename Safe Alphabet using UTF-8.
///</summary>
///<param name="str">Base64 code</param>
///<returns>The decoded string.</returns>
public static string Base64ForUrlDecode(string str)
{
    byte[] decbuff = HttpServerUtility.UrlTokenDecode(str);
    return Encoding.UTF8.GetString(decbuff);
}

Bahşiş için teşekkürler. Bunu bir dahaki sefere deneyeceğim!
Kirk Liemohn

12
Tavsiyeniz, bir saatin muhteşem sonuydu ve cevabı arayan saç tutamları. teşekkürler
Praesagus

Bu her / + ve = için% kodlamasını kullanmayacak mı? Bu, diğer cevap kadar verimli değil
JoelFan

Hayır, sonunda doldurma için kullanılan eşit işaretlerini bir sayı ile değiştirir ve artı ve eğik çizgiyi eksi ve alt çizgi ile değiştirir.
Fredrik Haglund

15
Kaç eşit işaretin değiştirildiğine bağlı olarak '=' dolgusunu '0', '1' veya '2' ile değiştirdiği için bunun UrlTokenEncodekesinlikle base64url olmadığını unutmayın .
ladenedge

28

Yorum yapmak için yeterli nokta yok, ancak yardımcı olması durumunda, Sushil'in sağlanan bağlantıda bulduğu kod parçacığı (JSON Web Signature ietf taslağı) Base 64'ü URL'de bir parametre olarak kodlarken işe yarar.

Tembel olanlar için aşağıdaki pasajı kopyalayın:

    static string Base64UrlEncode(byte[] arg)
    {
        string s = Convert.ToBase64String(arg); // Regular base64 encoder
        s = s.Split('=')[0]; // Remove any trailing '='s
        s = s.Replace('+', '-'); // 62nd char of encoding
        s = s.Replace('/', '_'); // 63rd char of encoding
        return s;
    }

    static byte[] Base64UrlDecode(string arg)
    {
        string s = arg;
        s = s.Replace('-', '+'); // 62nd char of encoding
        s = s.Replace('_', '/'); // 63rd char of encoding
        switch (s.Length % 4) // Pad with trailing '='s
        {
            case 0: break; // No pad chars in this case
            case 2: s += "=="; break; // Two pad chars
            case 3: s += "="; break; // One pad char
            default: throw new System.Exception(
              "Illegal base64url string!");
        }
        return Convert.FromBase64String(s); // Standard base64 decoder
    }

Bu, System.Web kullanmamak için Xamarin ile uyumludur
Reza Mortazavi

Tam olarak aradığım şey! Bir kitaplığı çekmek zorunda kalmadan Xamarin için gerçekten iyi bir seçenek.
Sleeping_Giant


5

Kabul cevap karşılaştırıldığında, burada nasıl olur temelden çözmek base64 kodlanmış url, C # kullanarak:

Kod Çözme:

string codedValue = "base64encodedUrlHere";

string decoded;
byte[] buffer =  Convert.FromBase64String(codedValue);
decoded = Encoding.UTF8.GetString(buffer);

belki daha fazla ayrıntı verirseniz ve kabul edilen yanıtla karşılaştırma yaparsanız, bir olumlu oy alabilirsiniz - teşekkürler
Mauricio Gracia Gutierrez
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.