2009-08-04 14 views
102

Tôi muốn dữ liệu mã hóa base64 để đặt nó vào một URL và sau đó giải mã nó trong HttpHandler của tôi.Mã để giải mã/mã hóa URL base64 đã sửa đổi

Tôi đã tìm thấy rằng Base64 Encoding cho phép ký tự '/' sẽ làm hỏng kết hợp UriTemplate của tôi. Sau đó, tôi thấy rằng có một khái niệm về "Base64 sửa đổi cho URL" từ wikipedia:

Biến thể Base64 cho biến thể URL tồn tại, nơi không có padding '=' sẽ được sử dụng, và '+' và '/' các ký tự của chuẩn Base64 được thay thế bằng '-' và '_', để sử dụng bộ giải mã/giải mã URL không còn cần thiết và không ảnh hưởng đến độ dài của giá trị được mã hóa, để nguyên dạng mã hóa tương tự để sử dụng trong cơ sở dữ liệu quan hệ , biểu mẫu web và số nhận dạng đối tượng nói chung.

Sử dụng .NET Tôi muốn sửa đổi mã hiện tại của mình bằng cách mã hóa và giải mã base64 cơ bản để sử dụng phương pháp "base64 cho URL" đã sửa đổi. Có ai đã làm điều này không?

Để giải mã, tôi biết nó bắt đầu với cái gì đó như:

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

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

// My normal base64 decoding now uses encodedText 

Nhưng, tôi cần phải có khả năng thêm một hoặc hai ký tự '=' vào cuối trông phức tạp hơn một chút.

lý mã hóa của tôi nên đơn giản hơn một chút:

// 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('/', '_'); 

Tôi đã thấy các StackOverflow nhập Guid to Base64 for URL, nhưng điều đó có chiều dài biết và vì vậy họ có thể hardcode số dấu bằng cần thiết ở cuối.

+0

@Kirk: Điều chỉnh câu trả lời của tôi bằng toán được kiểm tra. – AnthonyWJones

Trả lời

55

này phải pad nó ra một cách chính xác: -

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

Bah, bạn đánh tôi. Tôi sẽ chỉ xóa bài viết của tôi vì nó trông giống như tôi đã sao chép bạn :) – AaronLS

+2

Sẽ không thêm đến ba ký tự '=' này? Có vẻ như chỉ có 0, 1 hoặc 2 trong số này. –

+1

@Kirk: Nếu nó thêm 3 ký tự thì chuỗi base64 đã bị hỏng. Tôi đoán nó sẽ là một ý tưởng tốt để xác nhận chuỗi, nó chỉ nên chứa các ký tự mong đợi và Length% 4! = 3. – AnthonyWJones

168

Ngoài ra kiểm tra lớp HttpServerUtility với UrlTokenEncode và UrlTokenDecode phương pháp mà là xử lý URL mã hóa Base64 an toàn và giải mã.

Lưu ý 1: Kết quả không phải là chuỗi Base64 hợp lệ. Một số ký tự không an toàn cho URL được thay thế.

Lưu ý 2: Kết quả khác với thuật toán base64url trong RFC4648.

///<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); 
} 
+0

Cảm ơn mẹo. Tôi sẽ thử lần sau! –

+11

Mẹo của bạn là kết thúc vinh quang cho một giờ và tìm kiếm tóc tuft cho câu trả lời. cảm ơn – Praesagus

+0

Điều này thực hiện điều này ... –

18

Tôi hit ở đây trong khi tìm kiếm mã để làm mã hóa/giải mã cho mã hóa base64url đó là đôi chút khác biệt so với base64 như được giải thích trong câu hỏi.

Tìm thấy đoạn mã C# trong tài liệu này. JSON Web Signature ietf draft

+1

Đây là giải pháp duy nhất có hiệu quả đối với tôi khi phân tích cú pháp thư trong API GMail v1 (Thư.Nguyên) – HeyZiko

18

Không đủ điểm để nhận xét, nhưng trong trường hợp nó giúp, đoạn mã Sushil được tìm thấy trong liên kết được cung cấp (JSON Web Signature ietf draft) hoạt động khi mã hóa Base 64 làm tham số trong URL.

đoạn sao chép dưới đây cho những người lười biếng:

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 
    } 
+0

điều này tương thích với Xamarin vì không sử dụng System.Web –

3

So với các câu trả lời được chấp nhận, đây là cách bạn sẽ cơ bản decode một mã hóa base64 url, sử dụng C#:

Giải mã :

string codedValue = "base64encodedUrlHere"; 

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

có thể nếu bạn cung cấp thêm chi tiết và so sánh với câu trả lời được chấp nhận, bạn có thể nhận được một đề xuất - cảm ơn –