SQL Server 2005 T-SQL의 Base64 인코딩


124

문자열을 Base64 문자열로 인코딩하는 T-SQL 쿼리를 작성하고 싶습니다. 놀랍게도 Base64 인코딩을 수행하기위한 네이티브 T-SQL 함수를 찾을 수 없습니다. 네이티브 함수가 있습니까? 그렇지 않은 경우 T-SQL에서 Base64 인코딩을 수행하는 가장 좋은 방법은 무엇입니까?


1
왜 데이터를 base64 문자열로 저장해야하는지 궁금합니다. http를 통해 base64를 사용하는 좋은 이유가 있습니다. 즉, ASCII 문자 집합 만 지원하고 모든 데이터를 텍스트로 처리하는 시스템간에 상호 운용성을 보장하기 때문입니다. 바이트 배열을 base-64로 또는 그 반대로 쉽게 변환 할 수 있으므로 데이터를 효율적으로 저장하지 않는 이유는 무엇입니까? 사람들이 nvarchar 열에 base64 문자열을 저장하는 것을 보았습니다. 이는 varbinary 공간의 275 %를 차지하여 디스크, 램, 네트워크 등의 낭비로 이어집니다.
The Dag

9
이것은 base64 문자열을 생성하는 것이지 저장하는 것이 아닙니다.
Jacob

답변:


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
앞에, 당신은 'N'을 추가해야 유니 코드 문자 인코딩을 지원하기 위해 TestData 사용 : 'SELECT CAST을 ( N 'TestData 사용 'AS VARBINARY (MAX)) 빈 AS'
Kjetil Klaussen

유니 코드 텍스트에 대해 작동하지 않았습니다 ... 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

3
@hsuk varchar는 유니 코드와 호환되지 않습니다. 대신 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)유니 코드 문자열의 경우)


1
이것은 단지뿐만 아니라 다른 답변보다 훨씬 간단하고 작동
SXE

2
첫 번째 줄에서 BINARY BASE64의 목적은 무엇입니까? 필요합니까? 나는없이 시도했고 같은 결과를주는 것 같습니다.
mattpm

1
첫 번째 스 니펫은 예상과 다른 결과를 얻었습니다. 나는 "VARBINARY (최대)"에 "VARBINARY"를 변경하고 누락 된 문자는 제자리에 떨어졌다
Hraefn

3
실제 대답에는 문자열 리터럴이 필요하고이 대답과 같은 변수를 받아 들일 수 없기 때문에 이것은 대답이어야합니다.
Matthew

2
base64에서 문자열로의 경우 .value ( 'data [1]', 'varbinary (max)') 반대 .value ( '.', 'varbinary (max)')로 상당한 성능 향상을 알 수 있습니다.
기어 리 M. 매키 버는

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로 바꾼 후 처리
Oleg 19

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]

나를 위해 두 번째 줄 VARBINARY을 으로 변경 VARBINARY(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로 인코딩 된 기존 해시를 십진수로 변환하는 스크립트를 작성했는데 유용 할 수 있습니다.

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.