SQL Server 2005 T-SQLでのBase64エンコーディング


124

文字列をBase64文字列としてエンコードするT-SQLクエリを記述したいと思います。驚いたことに、Base64エンコーディングを実行するためのネイティブT-SQL関数が見つかりません。ネイティブ関数はありますか?そうでない場合、T-SQLでBase64エンコーディングを行うための最良の方法は何ですか?


1
データをbase64文字列として保存する必要がある理由を質問します。base64をhttpで使用することには十分な理由があります。つまり、ASCII文字セットのみをサポートする(そしてすべてのデータをテキストとして扱う)システム全体の相互運用性が保証されます。バイト配列をbase-64に、またはその逆に簡単に変換できるので、データを効率的に格納してみませんか?私は人々がbase64文字列をnvarchar列に格納するのを見たことさえあります。これはvarbinaryの領域の275%を占め、ディスク、RAM、ネットワークなどの無駄につながります
Dag

9
これは、base64文字列を生成することであり、格納することではありません。
ジェイコブ

回答:


187

私はこれがすでに回答されていることを知っていますが、これを達成するために単一行のSQLステートメントを考え出すことを認めるほどの時間を費やしたので、他の誰かが同じことをする必要がある場合に備えて、ここでそれらを共有します。

-- Encode the string "TestData" in Base64 to get "VGVzdERhdGE="
SELECT
    CAST(N'' AS XML).value(
          'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
        , 'VARCHAR(MAX)'
    )   Base64Encoding
FROM (
    SELECT CAST('TestData' AS VARBINARY(MAX)) AS bin
) AS bin_sql_server_temp;

-- Decode the Base64-encoded string "VGVzdERhdGE=" to get back "TestData"
SELECT 
    CAST(
        CAST(N'' AS XML).value(
            'xs:base64Binary("VGVzdERhdGE=")'
          , 'VARBINARY(MAX)'
        ) 
        AS VARCHAR(MAX)
    )   ASCIIEncoding
;

元の値( "TestData")を16進文字列表現( "5465737444617461")に変換して、引数として含める方法が見つからなかったため、最初の(エンコード)クエリでサブクエリ生成テーブルを使用する必要がありました。 XQueryステートメントのxs:hexBinary()。

これが誰かに役立つことを願っています!


7
エンコードする場合、xs:base64Binary(sql:column("bin"))xs:hexBinary呼び出しなしで)同様に機能します。大変助かります!
amphetamachine

3
Unicodeテキストのエンコードをサポートするには、TestDataの前に 'N'を追加する必要があります: 'SELECT CAST(N ' TestData 'AS VARBINARY(MAX))AS bin'
Kjetil Klaussen

Unicodeテキストでは機能しませんでした... SELECT CAST(N '' AS XML).value( 'xs:base64Binary(xs:hexBinary(sql:column( "bin")))'、 'VARCHAR(MAX)') Base64Encoding FROM(SELECT CAST(N 'मन्त्रीलेउल्ट्याएसातछन्。' AS VARBINARY(MAX))AS bin)AS bin_sql_server_temp;
hsuk 2013

3
@hsuk varcharはUnicodeと互換性がありません。代わりにnvarchar(max)を使用すると、正常に機能します。例:SELECT CAST( CAST(N'' AS XML).value( 'xs:base64Binary("LgkoCU0JJAlNCTAJQAkyCUcJIAAJCTIJTQkfCU0JLwk+CQ8JIAA4CT4JJAkgABsJKAlNCWQJ")' , 'VARBINARY(MAX)' ) AS NVARCHAR(MAX) ) UnicodeEncoding ;
AlwaysLearning

7
あなたがいつも予測できない理由のために時々人々はソフトウェアで特定のことを達成する必要があるので... ...
水銀

87

SQL Server 2012以降で私が見つけることができる最も簡単で最短の方法はBINARY BASE64次のとおりです。

SELECT CAST('string' as varbinary(max)) FOR XML PATH(''), BINARY BASE64

文字列へのBase64の場合

SELECT CAST( CAST( 'c3RyaW5n' as XML ).value('.','varbinary(max)') AS varchar(max) )

(またはnvarchar(max)Unicode文字列の場合)


1
これは他の回答よりもはるかに簡単で、同じように機能します
sXe

2
最初の行のBINARY BASE64の目的は何ですか?必要ですか?なしで試したところ、同じ結果が得られたようです。
mattpm 2016年

1
最初のスニペットでは、予想とは異なる結果が得られました。「varbinary」を「varbinary(max)」に変更し、欠落した文字が配置されました
Hraefn

3
実際の答えは文字列リテラルを必要とし、この答えのように変数を受け入れることができないため、これが答えになるはずです。
Matthew

2
base64から文字列の場合、.value( 'data [1]'、 'varbinary(max)')と.value( '。'、 'varbinary(max)')を使用すると、パフォーマンスが大幅に向上します。
Geary M. McIver 2017

25

これはMercuriialの回答に対する変更で、デコードでサブクエリも使用するため、両方のインスタンスで変数を使用できます。

DECLARE
    @EncodeIn VARCHAR(100) = 'Test String In',
    @EncodeOut VARCHAR(500),
    @DecodeOut VARCHAR(200)    

SELECT @EncodeOut = 
    CAST(N'' AS XML).value(
          'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
        , 'VARCHAR(MAX)'
    )
FROM (
    SELECT CAST(@EncodeIn AS VARBINARY(MAX)) AS bin
) AS bin_sql_server_temp;

PRINT @EncodeOut

SELECT @DecodeOut = 
CAST(
    CAST(N'' AS XML).value(
        'xs:base64Binary(sql:column("bin"))'
      , 'VARBINARY(MAX)'
    ) 
    AS VARCHAR(MAX)
) 
FROM (
    SELECT CAST(@EncodeOut AS VARCHAR(MAX)) AS bin
) AS bin_sql_server_temp;

PRINT @DecodeOut

22

これが仕事をする関数のコードです

-- To Base64 string
CREATE FUNCTION [dbo].[fn_str_TO_BASE64]
(
    @STRING NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    RETURN (
        SELECT
            CAST(N'' AS XML).value(
                  'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
                , 'NVARCHAR(MAX)'
            )   Base64Encoding
        FROM (
            SELECT CAST(@STRING AS VARBINARY(MAX)) AS bin
        ) AS bin_sql_server_temp
    )
END
GO

-- From Base64 string
CREATE FUNCTION [dbo].[fn_str_FROM_BASE64]
(
    @BASE64_STRING NVARCHAR(MAX)
)
RETURNS NVARCHAR(MAX)
AS
BEGIN
    RETURN (
        SELECT 
            CAST(
                CAST(N'' AS XML).value('xs:base64Binary(sql:variable("@BASE64_STRING"))', 'VARBINARY(MAX)') 
            AS NVARCHAR(MAX)
            )   UTF8Encoding
    )
END

使用例:

DECLARE @CHAR NVARCHAR(256) = N'e.g., سلام جیران or В России'
SELECT [dbo].[fn_str_FROM_BASE64]([dbo].[fn_str_TO_BASE64](@CHAR)) as converted

ここに画像の説明を入力してください


一般的に便利です。これは、ペルシャ語、ロシア語、または絵文字などの文字を処理しませんでした。例えば、سلامجیرانまたはВРоссииBase64でкодируетвасまたは❤️💥🤪🦌🎅⛄🎄🤐🙈🙉🙊💩
ハンター- Orionnoir

あなたが正しい。varcharをnvarcharに置き換えた後に処理されます
Oleg

8

@Slaiの答えが気に入りました。探していたワンライナーにほんのわずかな変更を加えるだけで済みました。私がしたように他の誰かがこのページにつまずくのを助ける場合に備えて、私が最終的に何をしたかを共有したいと思いました:

DECLARE @Source VARCHAR(50) = '12345'
DECLARE @Encoded VARCHAR(500) = CONVERT(VARCHAR(500), (SELECT CONVERT(VARBINARY, @Source) FOR XML PATH(''), BINARY BASE64))
DECLARE @Decoded VARCHAR(500) = CONVERT(VARCHAR(500), CONVERT(XML, @Encoded).value('.','varbinary(max)'))
SELECT @Source AS [Source], @Encoded AS [Encoded], @Decoded AS [Decoded]

私にとっては、私は2番目の行を変更するのに必要VARBINARYVARBINARY(56)して、それが働きました。
Lee Grissom

最短のソリューション、SQL Server 2005+互換。
YB


1
DECLARE @source varbinary(max),  
@encoded_base64 varchar(max),  
@decoded varbinary(max) 
SET @source = CONVERT(varbinary(max), 'welcome') 
-- Convert from varbinary to base64 string 
SET @encoded_base64 = CAST(N'' AS xml).value('xs:base64Binary(sql:variable       
("@source"))', 'varchar(max)') 
  -- Convert back from base64 to varbinary 
   SET @decoded = CAST(N'' AS xml).value('xs:base64Binary(sql:variable             
  ("@encoded_base64"))', 'varbinary(max)') 

 SELECT
  CONVERT(varchar(max), @source) AS [Source varchar], 
   @source AS [Source varbinary], 
     @encoded_base64 AS [Encoded base64], 
     @decoded AS [Decoded varbinary], 
     CONVERT(varchar(max), @decoded) AS [Decoded varchar]

これはエンコードとデコードに役立ちます。

Bharat J


0

base64でエンコードされた既存のハッシュを10進数に変換するスクリプトを実行しました。

SELECT LOWER(SUBSTRING(CONVERT(NVARCHAR(42), CAST( [COLUMN_NAME] as XML ).value('.','varbinary(max)'), 1), 3, 40)) from TABLE

-1

あなただけを使うことができます:

Declare @pass2 binary(32)
Set @pass2 =0x4D006A00450034004E0071006B00350000000000000000000000000000000000
SELECT CONVERT(NVARCHAR(16), @pass2)

エンコード後、テキスト「MjE4Nqk5」を受け取ります

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