簡體   English   中英

如何在 C# 中實現 Base64 URL 安全編碼?

[英]How to achieve Base64 URL safe encoding in C#?

我想在 C# 中實現 Base64 URL 安全編碼。 在 Java 中,我們有通用的Codec庫,它為我提供了一個 URL 安全編碼字符串。 如何使用 C# 實現相同的目標?

byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes("StringToEncode");
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);

上面的代碼將其轉換為 Base64,但它填充了== 有沒有辦法實現 URL 安全編碼?

通常簡單地交換字母表以用於 url,因此不需要 %-encoding; 65 個字符中只有 3 個有問題 - +/= 最常見的替換是-代替+_代替/ 至於填充:只需刪除它= ); 您可以推斷出所需的填充量。 在另一端:只需顛倒過程:

string returnValue = System.Convert.ToBase64String(toEncodeAsBytes)
        .TrimEnd(padding).Replace('+', '-').Replace('/', '_');

和:

static readonly char[] padding = { '=' };

並扭轉:

string incoming = returnValue
    .Replace('_', '/').Replace('-', '+');
switch(returnValue.Length % 4) {
    case 2: incoming += "=="; break;
    case 3: incoming += "="; break;
}
byte[] bytes = Convert.FromBase64String(incoming);
string originalText = Encoding.ASCII.GetString(bytes);

然而,有趣的問題是:這與“通用編解碼器庫”使用的方法相同嗎? 測試肯定是合理的第一件事 - 這是一種非常常見的方法。

您可以使用命名空間Microsoft.IdentityModel.Tokens Base64UrlEncoder類。

const string StringToEncode = "He=llo+Wo/rld";

var encodedStr = Base64UrlEncoder.Encode(StringToEncode);
var decodedStr = Base64UrlEncoder.Decode(encodedStr);

if (decodedStr == StringToEncode)
    Console.WriteLine("It works!");
else
    Console.WriteLine("Dangit!");

如果您使用 ASP.NET Core,另一種選擇是使用Microsoft.AspNetCore.WebUtilities.WebEncoders.Base64UrlEncode

如果您未使用 ASP.NET Core, WebEncodersApache 2.0 許可下使用WebEncoders

基於此處的答案以及一些性能改進,我們發布了一個非常易於使用的url-safe base64 實現到 NuGet ,其源代碼可在 GitHub 上獲得(MIT 許可)。

使用很簡單

var bytes = Encoding.UTF8.GetBytes("Foo");
var encoded = UrlBase64.Encode(bytes);
var decoded = UrlBase64.Decode(encoded);

要根據 RFC4648 獲得類似 URL 安全的 base64 編碼,但不是“base64url”,請使用System.Web.HttpServerUtility.UrlTokenEncode(bytes)進行編碼,使用System.Web.HttpServerUtility.UrlTokenDecode(bytes)進行解碼。

最簡單的解決方案:(無填充)

private static string Base64UrlEncode(string input) {
    var inputBytes = System.Text.Encoding.UTF8.GetBytes(input);
    // Special "url-safe" base64 encode.
    return Convert.ToBase64String(inputBytes)
      .Replace('+', '-') // replace URL unsafe characters with safe ones
      .Replace('/', '_') // replace URL unsafe characters with safe ones
      .Replace("=", ""); // no padding
  }

歸功於Tholle

這是另一種解碼 url-safe base64 的方法,其編碼方式與 Marc 相同。 我只是不明白為什么4-length%4有效(確實如此)。

如下,只有原點的位長是 6 和 8 的公倍數,base64 不附加“=”到結果。

1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8|1 2 3 4 5 6 7 8 
1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6|1 2 3 4 5 6
                "=="            "="

所以我們可以反過來做,如果結果的位長不能被 8 整除,則附加:

base64String = base64String.Replace("-", "+").Replace("_", "/");
var base64 = Encoding.ASCII.GetBytes(base64String);
var padding = base64.Length * 3 % 4;//(base64.Length*6 % 8)/2
if (padding != 0)
{
    base64String = base64String.PadRight(base64String.Length + padding, '=');
}
return Convert.FromBase64String(base64String);

在 UWP 中使用 Microsoft 加密引擎。

uint length = 32;

IBuffer buffer = CryptographicBuffer.GenerateRandom(length);
string base64Str = CryptographicBuffer.EncodeToBase64String(buffer)
                   // ensure url safe
                   .TrimEnd('=').Replace('+', '-').Replace('/', '_');

return base64Str;

Karanvir Kang 的回答很好,我投了贊成票。 但是,它確實在字符串的末尾留下了一個奇數字符(表示刪除的填充字符數)。 這是我的解決方案。

var bytesToEncode = System.Text.Encoding.UTF8.GetBytes("StringToEncode"); 
var bytesEncodedPadded = HttpServerUtility.UrlTokenEncode(bytesToEncode);
var objectIdBase64 = bytesEncodedPadded.Substring(0, bytesEncodedPadded.Length - 1);
    public string Decode(string str)
    {
       byte[] decbuff = Convert.FromBase64String(str.Replace(",", "=").Replace("-", "+").Replace("/", "_"));
       return System.Text.Encoding.UTF8.GetString(decbuff);
    }
    
    public string Encode(string input)
    {
        byte[] encbuff = Encoding.UTF8.GetBytes(input ?? "");
        return Convert.ToBase64String(encbuff).Replace("=", ",").Replace("+", "-").Replace("_", "/");
    }

這是與 JavaScript 保持一致的方法!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM