SQL Server 2005 T-SQL中的Base64编码


124

我想编写一个T-SQL查询,在其中将字符串编码为Base64字符串。令人惊讶的是,我找不到用于执行Base64编码的任何本机T-SQL函数。是否存在本机功能?如果不是,在T-SQL中执行Base64编码的最佳方法是什么?


1
我想问为什么数据应该存储为base64字符串。在http上使用base64是有充分的理由的,即它可以确保跨系统的互操作性,这些系统仅支持ASCII字符集(并将所有数据视为文本)。您可以轻松地将字节数组转换为base-64,反之亦然,那么为什么不高效地存储数据呢?我甚至见过人们存储的base64字符串nvarchar列,这需要275%VARBINARY的空间,导致浪费磁盘,内存,网络等
达格

9
这是关于生成一个base64字符串,而不是存储一个。
2014年

Answers:


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”)转换为其十六进制字符串表示形式(“ 5465737444617461”)以作为参数XQuery语句中的xs:hexBinary()。

我希望这可以帮助别人!


7
编码时,xs:base64Binary(sql:column("bin"))(无需xs:hexBinary调用)也可以正常工作。很大的帮助!
amphetamachine

3
为了支持前面Unicode文本编码,您应该添加'N' TESTDATA: 'SELECT CAST(ñ 'TESTDATA' AS VARBINARY(MAX))AS斌'
的Kjetil Klaussen

不适用于unicode文本... SELECT CAST(N''AS XML).value('xs:base64Binary(xs:hexBinary(sql:column(“ bin”)))','VARCHAR(MAX)') Base64Encoding FROM((选择AST(VARBINARY(MAX))AS bin)AS bin_sql_server_temp;
hsuk

3
@hsuk varchar与Unicode不兼容。如果您改用nvarchar(max),则效果很好,例如:SELECT CAST( CAST(N'' AS XML).value( 'xs:base64Binary("LgkoCU0JJAlNCTAJQAkyCUcJIAAJCTIJTQkfCU0JLwk+CQ8JIAA4CT4JJAkgABsJKAlNCWQJ")' , 'VARBINARY(MAX)' ) AS NVARCHAR(MAX) ) UnicodeEncoding ;
AlwaysLearning 2013年

7
因为有时人们出于某些原因无法总是预测到某些原因而需要在软件中完成某些事情?
2014年

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 2015年

2
第一行中BINARY BASE64的用途是什么?需要吗?我尝试了没有,它似乎给出了相同的结果。
mattpm

1
第一个片段给了我与预期不同的结果;我将“ varbinary”更改为“ varbinary(max)”,丢失的字符就位了
Hraefn

3
这应该是答案,因为实际答案需要字符串文字,并且不能像该答案那样接受变量。
马修

2
对于base64到字符串,我注意到使用.value('data [1]','varbinary(max)')副.value('。','varbinary(max)')可获得明显的性能提升。
Geary M. McIver'7

25

这是对mercurial答案的修改,该修改也使用了解码中的子查询,从而允许在两种情况下都使用变量。

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的后处理
奥列格

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]

对我来说,我需要将第二行更改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]

这对于编码和解码很有用。

巴拉特J


0

我做了一个脚本,将以base64编码的现有哈希转换为十进制,这可能很有用:

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”

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.