web-dev-qa-db-fra.com

Encodage Base64 dans SQL Server 2005 T-SQL

J'aimerais écrire une requête T-SQL dans laquelle je code une chaîne en tant que chaîne Base64. De manière surprenante, je ne trouve aucune fonction T-SQL native pour l’encodage Base64. Une fonction native existe-t-elle? Sinon, quel est le meilleur moyen de coder en Base64 dans T-SQL?

106
Jacob

Je sais que la réponse à cette question a déjà été donnée, mais je viens de passer plus de temps que nécessaire à admettre que des instructions SQL monolignes soient utilisées à cette fin. Je vais donc les partager ici au cas où quelqu'un d'autre aurait à faire de même:

-- 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
;

J'ai dû utiliser une table générée par une sous-requête dans la première requête (codage) car je ne trouvais aucun moyen de convertir la valeur d'origine ("TestData") en une représentation chaîne hexadécimale ("5465737444617461") à inclure comme argument. xs: hexBinary () dans l'instruction XQuery.

J'espère que ça aidera quelqu'un!

169
mercurial

Le moyen le plus simple et le plus court que j'ai trouvé pour SQL Server 2012 et versions supérieures est BINARY BASE64 :

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

Pour Base64 to string

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

(ou nvarchar(max) pour les chaînes Unicode)

66
Slai

Voici une modification de la réponse de Mercurial qui utilise également la sous-requête du décodage, permettant l'utilisation de variables dans les deux cas.

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
Joey Gennari

Voici le code pour les fonctions qui feront le travail

-- 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
21
Oleg

J'ai adoré la réponse de @ Slai. Je n'ai eu qu'à apporter des modifications très mineures aux one-liners que je cherchais. Je pensais partager ce que je trouvais si cela pouvait aider quelqu'un d'autre à trébucher sur cette page, comme je l'ai fait:

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]
6
Jason W

Non, il n'y a pas de fonction native, cette méthode a fonctionné pour moi dans le passé: http://www.motobit.com/help/scptutl/sa306.htm
ainsi a cette méthode:
http://www.vbforums.com/showthread.php?t=554886

4
ntziolis
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]

Ceci est utile pour encoder et décoder.

Par Bharat J

1
Bharat J

J'ai fait un script pour convertir un hachage existant encodé en base64 en décimal, cela peut être utile:

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

Vous pouvez utiliser simplement:

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

puis après l'encodage, vous recevrez le texte 'MjE4Nqk5'

0
jasmintmp