変更されたbase64 URLをデコード/エンコードするためのコード


113

データをbase64でエンコードしてURLに配置し、HttpHandler内でデコードしたいと考えています。

Base64エンコードでは、UriTemplateの一致を台無しにする「/」文字が許可されることがわかりました。次に、Wikipediaから「URLのBase64を変更する」という概念があることがわかりました。

URLバリアントの変更されたBase64が存在し、パディング「=」は使用されず、標準のBase64の「+」および「/」文字はそれぞれ「-」および「_」に置き換えられるため、URLエンコーダー/デコーダーを使用するは不要になり、エンコードされた値の長さに影響を与えません。同じエンコードされたフォームをそのままリレーショナルデータベース、Webフォーム、およびオブジェクト識別子で使用するために残します。

.NETを使用して、現在のコードを基本的なbase64エンコードおよびデコードから「変更されたbase64 for base64」メソッドを使用するように変更したいと思います。誰かこれをやったことがありますか?

デコードするには、次のようなものから始めます。

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

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

// My normal base64 decoding now uses encodedText

しかし、私は潜在的に1つまたは2つの「=」文字を最後に追加する必要がありますが、これは少し複雑に見えます。

私のエンコーディングロジックはもう少し単純なはずです。

// 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エントリのBase64Guidを確認しましたが、その長さはわかっているため、最後に必要な等号の数をハードコードできます。


@カーク:テストされた数学で私の答えを調整します。
AnthonyWJones 2009

回答:


69

これはそれを正しく埋め込むべきです:-

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

11
ああ、あなたは私を倒した。私はあなたをコピーしたように見えるので、私の投稿を削除します:)
AaronLS

3
これは合計で3つの「=」文字になりますか?これらは0、1、または2しかないようです。
Kirk Liemohn、2009

1
@カーク:3文字追加した場合、base64文字列は既に破損しています。私はそれが唯一の期待と長さ%4文字が含まれている必要があり、文字列を検証するために良いでしょう推測= 3!
AnthonyWJones

うーん。これを試してみると、それはトリックをしていません。まだ答えを探しています。等号の数が正しくパンニングされていません。
Kirk Liemohn、2009

2
@AnthonyWJones '期待される文字と長さ%4!= 1のみを含める必要がありますよね?
13

173

また、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);
}

先端をありがとう。次回もやってみます!
Kirk Liemohn、2009年

12
あなたのヒントは、答えを探すための数時間と毛房探索の輝かしい終わりでした。感謝
Praesagus 2010

これはすべての/ +と=に%エンコーディングを使用しませんか?これは他の回答ほど効率的ではありません
JoelFan

いいえ、最後にパディングに使用される等号を数字に置き換え、プラスとスラッシュをマイナスとアンダースコアに置き換えます。
Fredrik Haglund 2012年

15
UrlTokenEncodeは、厳密にbase64urlではないことに注意してください。置換した等号の数に応じて、「=」のパディングが「0」、「1」、または「2」に置き換えられるためです。
ladenedge 2012

28

コメントするのに十分なポイントではありませんが、役立つ場合は、提供されたリンク(JSON Web Signature ietfドラフト)で検出されたコードが、Base 64をURLのパラメーターとしてエンコードするときに機能します。

怠惰なもののために以下のスニペットをコピーしました:

    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と互換性があります
Reza Mortazavi 2017年

まさに探していたもの!ライブラリをプルする必要がないXamarinの本当に良いオプション。
Sleeping_Giant

19

質問で説明されているように、base64とほとんど変わらないbase64urlエンコーディングのエンコード/デコードを行うコードを探しているときに、私はここに行きました。

このドキュメントでc#コードスニペットを見つけました。JSON Web Signature ietfドラフト


2
これは、GMail API v1(Message.Raw)でメッセージを解析するときに機能した唯一のソリューションでした
HeyZiko

5

受け入れられた回答と比較して、C#を使用してbase64でエンコードされたURL を基本的にデコードする方法を次に示します。

デコード:

string codedValue = "base64encodedUrlHere";

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

多分あなたがより多くの詳細と受け入れられた回答との比較を提供するならば、あなたは賛成票を得るかもしれません-感謝
Mauricio Gracia Gutierrez
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.