用于解码/编码修改后的 base64 URL 的代码

Posted

技术标签:

【中文标题】用于解码/编码修改后的 base64 URL 的代码【英文标题】:Code for decoding/encoding a modified base64 URL (in ASP.NET Framework) 【发布时间】:2010-11-16 18:06:23 【问题描述】:

我想对数据进行 base64 编码以将其放入 URL 中,然后在我的 HttpHandler 中对其进行解码。

我发现Base64 Encoding 允许使用“/”字符,这会弄乱我的 UriTemplate 匹配。然后我从***发现有一个“为 URL 修改 Base64”的概念:

存在一个修改过的 Base64 for URL 变体,其中不使用填充“=”,标准 Base64 的“+”和“/”字符分别替换为“-”和“_”,以便使用 URL不再需要编码器/解码器,并且对编码值的长度没有影响,保持相同的编码形式完好无损,可用于一般的关系数据库、Web 表单和对象标识符。

使用 .NET 我想将我当前的代码从进行基本的 base64 编码和解码修改为使用“修改后的 base64 for URL”方法。有人做过吗?

要解码,我知道它从以下内容开始:

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

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

// My normal base64 decoding now uses encodedText

但是,我可能需要在末尾添加一两个“=”字符,这看起来有点复杂。

我的编码逻辑应该简单一点:

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

我见过Guid to Base64 for URL *** 条目,但它的长度是已知的,因此他们可以硬编码最后所需的等号数量。

【问题讨论】:

【参考方案1】:

与已接受的答案相比,以下是使用 C# 从根本上解码 base64 编码的 url:

解码:

string codedValue = "base64encodedUrlHere";

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

【讨论】:

也许如果您提供更多详细信息并与已接受的答案进行比较,您可能会获得支持 - 谢谢 不是base64编码的URL,而是base64url编码的数据。【参考方案2】:

没有足够的评论点,但如果有帮助,Sushil 在提供的链接(JSON Web 签名 ietf 草案)中找到的代码 sn-p 适用于将 Base 64 编码为 URL 中的参数。

为那些懒惰的人复制下面的sn-p:

    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
    

【讨论】:

这与不使用 System.Web 的 Xamarin 兼容 正是我想要的! Xamarin 的真正好选择,无需拉入库。【参考方案3】:

还可以使用处理 URL 安全 Base64 编码和解码的 UrlTokenEncode 和 UrlTokenDecode 方法检查类 HttpServerUtility

注意 1:结果不是有效的 Base64 字符串。 URL 的一些不安全字符已被替换。

注意2:结果与RFC4648中的base64url算法不同。

///<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);

【讨论】:

你的小费是一个多小时和头发簇搜索答案的光荣结束。谢谢 这不会对每个 / + 和 = 使用 % 编码吗?这不如其他答案有效 不,它用数字替换最后用于填充的等号,并将加号和斜杠替换为减号和下划线。 请注意,UrlTokenEncode 并不是严格意义上的base64url,因为它会根据替换的等号数量将 '=' 填充替换为 '0'、'1' 或 '2'。 【参考方案4】:

我在寻找代码来对 base64url 编码进行编码/解码时点击这里,这与问题中解释的 base64 略有不同。

在本文档中找到 c# 代码 sn-p。 JSON Web Signature ietf draft

【讨论】:

这是在 GMail API v1 (Message.Raw) 中解析消息时唯一对我有用的解决方案【参考方案5】:

这应该正确地填充它:-

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

【讨论】:

呸,你打败了我。我将删除我的帖子,因为它看起来几乎像我复制了你:) 这不会加起来三个 '=' 字符吗?似乎只有 0、1 或 2 个。 @Kirk:如果它添加了 3 个字符,那么 base64 字符串已经损坏。我想验证字符串是个好主意,它应该只包含预期的字符和 Length % 4 != 3。 嗯。在尝试这一点时,它并没有起到作用。仍在寻找答案。等号的数量没有正确平移。 @AnthonyWJones '它应该只包含预期的字符和 Length % 4 != 1',对吗?

以上是关于用于解码/编码修改后的 base64 URL 的代码的主要内容,如果未能解决你的问题,请参考以下文章

python使用base64编码解码数据

base64编码解码

将base64URL解码为base64 - Swift

URL安全的Base64编码,解码

java 怎么实现PHP的base64加密,两种语言的base64加密后的数据不一致

Base64编解码 ---- 支持64编码