SQL Server 2005 T-SQL中的Base64编码

时间:2011-02-22 18:37:37

标签: sql-server-2005 tsql encoding base64

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

10 个答案:

答案 0 :(得分:173)

我知道这已经得到了解答,但是我花了更多的时间来承认用单行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”)以包含as XQuery语句中xs:hexBinary()的参数。

我希望这有助于某人!

答案 1 :(得分:22)

这是对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

答案 2 :(得分:21)

以下是将完成工作的函数的代码

-- To Base64 string
CREATE FUNCTION [dbo].[fn_str_TO_BASE64]
(
    @STRING VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    RETURN (
        SELECT
            CAST(N'' AS XML).value(
                  'xs:base64Binary(xs:hexBinary(sql:column("bin")))'
                , 'VARCHAR(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 VARCHAR(MAX)
)
RETURNS VARCHAR(MAX)
AS
BEGIN
    RETURN (
        SELECT 
            CAST(
                CAST(N'' AS XML).value('xs:base64Binary(sql:variable("@BASE64_STRING"))', 'VARBINARY(MAX)') 
            AS VARCHAR(MAX)
            )   UTF8Encoding
    )
END

答案 3 :(得分:6)

我喜欢@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]

答案 4 :(得分:4)

不,没有原生功能,这种方法过去对我有用: http://www.motobit.com/help/scptutl/sa306.htm
这种方法也是如此:
http://www.vbforums.com/showthread.php?t=554886

答案 5 :(得分: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

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

您只能使用:

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

然后,编码后您将收到文本“ MjE4Nqk5”

答案 8 :(得分:0)

从以上所有答案中提取内容,这就是我的想法。

基本上有两种方法可以做到这一点:

;WITH TMP AS (
    SELECT CAST(N'' AS XML).value('xs:base64Binary(xs:hexBinary(sql:column("bin")))', 'VARCHAR(MAX)') as  Base64Encoding
    FROM 
    (
        SELECT TOP 10000 CAST(Words AS VARBINARY(MAX)) AS bin FROM TestData
    ) SRC
) 

SELECT *, CAST(CAST(N'' AS XML).value('xs:base64Binary(sql:column("Base64Encoding"))', 'VARBINARY(MAX)') AS NVARCHAR(MAX)) as ASCIIEncoding
FROM
(
    SELECT * FROM TMP
) SRC

第二种方式

;WITH TMP AS 
(
    SELECT TOP 10000 CONVERT(VARCHAR(MAX), (SELECT CAST(Wordsas varbinary(max)) FOR XML PATH(''))) as BX
    FROM TestData
)

SELECT *, CONVERT(NVARCHAR(MAX), CONVERT(XML, BX).value('.','varbinary(max)'))
FROM TMP

在比较性能时,第一个具有2.4414的子树成本,第二个具有4.1538的子树成本。这意味着第一个速度大约是第二个速度的两倍(这是可以预料的,因为它使用的是XML,这非常慢)。

答案 9 :(得分:0)

以 2015 年“Slai”的回答为基础,但按顺序编写:

declare @s as varchar(max) 
declare @b64 as varchar(max) 

-- encode varchar to base64 varchar
set @s  = 'Hello Base64'
set @b64  = (select CAST(@s as varbinary(max)) FOR XML PATH(''), BINARY BASE64)
select @s source, @b64 b86Encoded

-- decode base64 varchar 
set @b64 = 'SGVsbG8gQmFzZTY0'
set @s = CAST( CAST( @b64 as XML ).value('.','varbinary(max)') AS varchar(max) )
select @b64 b64Encoded, @s decoded