base64文字列をエンコードおよびデコードするにはどうすればよいですか?


885
  1. 文字列を指定してbase64でエンコードされた文字列を返すにはどうすればよいですか?

  2. base64でエンコードされた文字列を文字列にデコードするにはどうすればよいですか?


4
これが「知識を共有する」質問と回答である場合、私はもう少し詳細なものを探していると思います。また、SOのクイック検索が表示されます。stackoverflow.com
Kev

1
@Gnark任意の文字列は、特定の基本的なビットエンコードスキーマによってエンコードされます。それがASCII、UTF7、UTF8などであるとする。
Lorenz Lo Sauer、

2
本当にこれを行う必要があるか自問してください。base64は、主にバイナリデータをASCIIで表すこと、データベースのcharフィールドに格納すること、または電子メール(新しい行を挿入できる場所)経由で送信することを目的としています。文字データを取得してバイトに変換してから、文字データに変換しますか?今回は読み取り不可能で、元のエンコードが何であったかについてのヒントはありませんか?
bbsimonbb

元のエンコーディングを気にする必要があるのはなぜですか?すべての可能な文字列文字を表すことができるUTF8表現を使用して、文字列をバイトにエンコードします。次に、そのデータをシリアル化し、もう一方の端でそのデータを逆シリアル化して、最初に持っていたのと同じ文字列を再構築します(文字列オブジェクトは、とにかく使用されるエンコードに関する情報を保持していません)。それで、使用されているエンコーディングに関連する懸念があるのはなぜですか?これは、シリアル化されたデータを表す独自の方法と考えることができます。
Mladen B.

回答:


1668

エンコード

public static string Base64Encode(string plainText) {
  var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
  return System.Convert.ToBase64String(plainTextBytes);
}

デコード

public static string Base64Decode(string base64EncodedData) {
  var base64EncodedBytes = System.Convert.FromBase64String(base64EncodedData);
  return System.Text.Encoding.UTF8.GetString(base64EncodedBytes);
}

41
Nullは両方の関数で入力文字列をチェックし、解決策は完璧です:)
Sverrir Sigmundarson 14年

22
@SverrirSigmundarson:それか、拡張メソッドにします。
TJクラウダー2014

73
@SverrirSigmundarson-なぜnullチェックを行うのですか?入力文字列を逆参照するのは彼ではありません。nullチェックはNullReferenceException、他の誰かのコードではなく、自分のコードで防ぐ必要があります。

16
@kenそして、他の誰かが「他の誰かのエラーではなく、自分のコードのエラーのみを公開するべきだ」と言うでしょう。これは、下位レベルのコンポーネントのエラーをラップすることを意味する場合もあれば、完全に別の場合もあります。この場合、参照解除エラーをラップすることは間違いなく疑わしいことに同意します(さらに、概念としてのnullは最初は少しハックであるという事実にゆっくりと同意します)が、依然としていくつかの影響を見ることができますそれ以外の場合:例外で指定されたパラメーター名は、チェックされていない場合、正しくない可能性があります。
2015

6
return System.Text.Encoding.UTF8.GetString(base64EncodedBytes、0、base64EncodedBytes.Length); Windows Phone 8の場合
steveen zoleko

46

私の実装をいくつかのきちんとした機能と共有しています:

  • Encodingクラスの拡張メソッドを使用します。理論的根拠は、誰かが(UTF8だけでなく)異なるタイプのエンコーディングをサポートする必要があるかもしれないということです。
  • 別の改善点は、nullエントリのnull結果で正常に失敗することです。これは実際のシナリオで非常に役立ち、X = decode(encode(X))の同等性をサポートします。

備考:拡張メソッドを使用するには、名前空間をキーワード(この場合は)でインポートする(!)必要あることに注意してください。usingusing MyApplication.Helpers.Encoding

コード:

namespace MyApplication.Helpers.Encoding
{
    public static class EncodingForBase64
    {
        public static string EncodeBase64(this System.Text.Encoding encoding, string text)
        {
            if (text == null)
            {
                return null;
            }

            byte[] textAsBytes = encoding.GetBytes(text);
            return System.Convert.ToBase64String(textAsBytes);
        }

        public static string DecodeBase64(this System.Text.Encoding encoding, string encodedText)
        {
            if (encodedText == null)
            {
                return null;
            }

            byte[] textAsBytes = System.Convert.FromBase64String(encodedText);
            return encoding.GetString(textAsBytes);
        }
    }
}

使用例:

using MyApplication.Helpers.Encoding; // !!!

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Test1();
            Test2();
        }

        static void Test1()
        {
            string textEncoded = System.Text.Encoding.UTF8.EncodeBase64("test1...");
            System.Diagnostics.Debug.Assert(textEncoded == "dGVzdDEuLi4=");

            string textDecoded = System.Text.Encoding.UTF8.DecodeBase64(textEncoded);
            System.Diagnostics.Debug.Assert(textDecoded == "test1...");
        }

        static void Test2()
        {
            string textEncoded = System.Text.Encoding.UTF8.EncodeBase64(null);
            System.Diagnostics.Debug.Assert(textEncoded == null);

            string textDecoded = System.Text.Encoding.UTF8.DecodeBase64(textEncoded);
            System.Diagnostics.Debug.Assert(textDecoded == null);
        }
    }
}

5
null場合に戻ることはnull非常に一貫性のない動作です。文字列で動作する他の.net APIはこれを行いません。
t3chb0t

4
@ t3chb0tは、必要に応じて自由に調整してください。ここに表示される方法は、私たちのものに調整されました。これは公開APIではありません;)
andrew.fox

1
2つの変数を(base64でエンコードされたデータを送信する)通信の相手に送信する必要はありませんか?使用するエンコーディングと実際のbase64データの両方を送信する必要がありますか?同じエンコーディングを使用するために両側で規則を使用する方が簡単ではないですか?そうすれば、base64データを送信するだけで済みますよね?
Mladen B.

38

Andrew FoxとCebeの回答に基づいて、私はそれを裏返し、Base64String拡張ではなく文字列拡張にしました。

public static class StringExtensions
{
    public static string ToBase64(this string text)
    {
        return ToBase64(text, Encoding.UTF8);
    }

    public static string ToBase64(this string text, Encoding encoding)
    {
        if (string.IsNullOrEmpty(text))
        {
            return text;
        }

        byte[] textAsBytes = encoding.GetBytes(text);
        return Convert.ToBase64String(textAsBytes);
    }

    public static bool TryParseBase64(this string text, out string decodedText)
    {
        return TryParseBase64(text, Encoding.UTF8, out decodedText);
    }

    public static bool TryParseBase64(this string text, Encoding encoding, out string decodedText)
    {
        if (string.IsNullOrEmpty(text))
        {
            decodedText = text;
            return false;
        }

        try
        {
            byte[] textAsBytes = Convert.FromBase64String(text);
            decodedText = encoding.GetString(textAsBytes);
            return true;
        }
        catch (Exception)
        {
            decodedText = null;
            return false;
        }
    }
}

1
私は必要な場合に例外を投入するために((文字列decodedTextから、エンコーディングエンコーディング、この文字列テキスト)ParseBase64を追加し、コールすることをTryParseBase64に
ジョアン・アントゥネス

22

デコードする文字列が正しいbase64エンコードされた文字列ではない可能性があるため、andrew.foxの回答のわずかなバリエーション:

using System;

namespace Service.Support
{
    public static class Base64
    {
        public static string ToBase64(this System.Text.Encoding encoding, string text)
        {
            if (text == null)
            {
                return null;
            }

            byte[] textAsBytes = encoding.GetBytes(text);
            return Convert.ToBase64String(textAsBytes);
        }

        public static bool TryParseBase64(this System.Text.Encoding encoding, string encodedText, out string decodedText)
        {
            if (encodedText == null)
            {
                decodedText = null;
                return false;
            }

            try
            {
                byte[] textAsBytes = Convert.FromBase64String(encodedText);
                decodedText = encoding.GetString(textAsBytes);
                return true;
            }
            catch (Exception)
            {
                decodedText = null;
                return false;   
            }
        }
    }
}

13

以下のルーチンを使用して、文字列をbase64形式に変換できます

public static string ToBase64(string s)
{
    byte[] buffer = System.Text.Encoding.Unicode.GetBytes(s);
    return System.Convert.ToBase64String(buffer);
}

また、非常に優れたオンラインツールOnlineUtility.inを使用して、文字列をbase64形式でエンコードできます。


オンラインツールはこの状況では役に立ちません-彼はITのコーディング方法を尋ねています。私の人々が言う理由は、多くの場合、不思議、OPは、オンラインツールを求めていなかったため、「このオンラインツールをチェックしてください!」:D
Momoro

9
    using System;
    using System.Text;

    public static class Base64Conversions
    {
        public static string EncodeBase64(this string text, Encoding encoding = null)
        { 
            if (text == null) return null;

            encoding = encoding ?? Encoding.UTF8;
            var bytes = encoding.GetBytes(text);
            return Convert.ToBase64String(bytes);
        }

        public static string DecodeBase64(this string encodedText, Encoding encoding = null)
        {
            if (encodedText == null) return null;

            encoding = encoding ?? Encoding.UTF8;
            var bytes = Convert.FromBase64String(encodedText);
            return encoding.GetString(bytes);
        }
    }

使用法

    var text = "Sample Text";
    var base64 = text.EncodeBase64();
    base64 = text.EncodeBase64(Encoding.UTF8); //or with Encoding

4

URLセーフのBase64エンコード/デコード

public static class Base64Url
{
    public static string Encode(string text)
    {
        return Convert.ToBase64String(Encoding.UTF8.GetBytes(text)).TrimEnd('=').Replace('+', '-')
            .Replace('/', '_');
    }

    public static string Decode(string text)
    {
        text = text.Replace('_', '/').Replace('-', '+');
        switch (text.Length % 4)
        {
            case 2:
                text += "==";
                break;
            case 3:
                text += "=";
                break;
        }
        return Encoding.UTF8.GetString(Convert.FromBase64String(text));
    }
}

1
質問はURLエンコーディングに関するものではありませんでしたが、それでも役に立ちました..
Momoro

おっと、間違った質問の下に投稿しました
juliushuck

問題ありません。URLをエンコード/デコードする方法を見るのも興味深いです:)
Momoro

3

次のように表示できます。

var strOriginal = richTextBox1.Text;

byte[] byt = System.Text.Encoding.ASCII.GetBytes(strOriginal);

// convert the byte array to a Base64 string
string strModified = Convert.ToBase64String(byt);

richTextBox1.Text = "" + strModified;

今、それを元に戻します。

var base64EncodedBytes = System.Convert.FromBase64String(richTextBox1.Text);

richTextBox1.Text = "" + System.Text.Encoding.ASCII.GetString(base64EncodedBytes);
MessageBox.Show("Done Converting! (ASCII from base64)");

これが役に立てば幸いです!


1

単に個々のbase64桁をエンコード/デコードしたい場合:

public static int DecodeBase64Digit(char digit, string digit62 = "+-.~", string digit63 = "/_,")
{
    if (digit >= 'A' && digit <= 'Z') return digit - 'A';
    if (digit >= 'a' && digit <= 'z') return digit + (26 - 'a');
    if (digit >= '0' && digit <= '9') return digit + (52 - '0');
    if (digit62.IndexOf(digit) > -1)  return 62;
    if (digit63.IndexOf(digit) > -1)  return 63;
    return -1;
}

public static char EncodeBase64Digit(int digit, char digit62 = '+', char digit63 = '/')
{
    digit &= 63;
    if (digit < 52)
        return (char)(digit < 26 ? digit + 'A' : digit + ('a' - 26));
    else if (digit < 62)
        return (char)(digit + ('0' - 52));
    else
        return digit == 62 ? digit62 : digit63;
}

数字62と63に何を使用するかについて意見が異なる Base64のさまざまなバージョンがあるためDecodeBase64Digit、これらのいくつかを許容できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.