Mã hóa Base64 trong SQL Server 2005 T-SQL


124

Tôi muốn viết một truy vấn T-SQL trong đó tôi mã hóa một chuỗi dưới dạng chuỗi Base64. Đáng ngạc nhiên, tôi không thể tìm thấy bất kỳ hàm T-SQL gốc nào để thực hiện mã hóa Base64. Có một chức năng bản địa tồn tại? Nếu không, cách tốt nhất để mã hóa Base64 trong T-SQL là gì?


1
Tôi muốn hỏi tại sao dữ liệu nên được lưu trữ dưới dạng chuỗi base64. Có một lý do chính đáng để sử dụng base64 trên http, cụ thể là nó đảm bảo khả năng tương tác giữa các hệ thống không hỗ trợ gì nhiều hơn bộ ký tự ASCII (và coi tất cả dữ liệu là văn bản). Bạn có thể dễ dàng chuyển đổi một mảng byte thành base-64 và ngược lại, vậy tại sao không lưu trữ dữ liệu hiệu quả? Tôi thậm chí đã từng thấy mọi người lưu trữ các chuỗi cơ sở 64 trong các cột nvarchar, chiếm tới 275% không gian của varbinary, dẫn đến lãng phí đĩa, ram, mạng, v.v.
The Dag

9
Đây là về việc tạo một chuỗi base64, không lưu trữ một chuỗi.
Jacob

Câu trả lời:


187

Tôi biết điều này đã được trả lời, nhưng tôi chỉ mất nhiều thời gian hơn tôi quan tâm đến việc đưa ra các câu lệnh SQL một dòng để thực hiện điều này, vì vậy tôi sẽ chia sẻ chúng ở đây trong trường hợp bất kỳ ai khác cần phải làm như vậy:

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

Tôi đã phải sử dụng bảng được tạo bởi truy vấn con trong truy vấn (mã hóa) đầu tiên vì tôi không thể tìm thấy bất kỳ cách nào để chuyển đổi giá trị ban đầu ("TestData") thành biểu diễn chuỗi hex ("5465737444617461") để đưa vào làm đối số xs: hexBinary () trong câu lệnh XQuery.

Tôi hi vọng điêu nay se giup được ai đo!


7
Khi mã hóa, xs:base64Binary(sql:column("bin"))(không có xs:hexBinarycuộc gọi) cũng hoạt động. Giúp đỡ nhiều!
amphetamachine

3
Để hỗ trợ mã hóa văn bản unicode, bạn nên thêm 'N' vào trước TestData : 'CHỌN CAST ( N ' TestData 'AS VARBINARY (MAX)) AS bin'
Kjetil Klaussen

Không hoạt động đối với văn bản unicode ... CHỌN CAST (N '' AS XML) .value ('xs: base64Binary (xs: hexBinary (sql: cột ("bin")))', 'VARCHAR (MAX)') Base64Encoding TỪ (CHỌN CAST (N 'मन तीीीेेेेेेेेेे
hsuk

3
@hsuk varchar không tương thích với Unicode. Nó hoạt động tốt nếu bạn sử dụng nvarchar (tối đa) thay vào đó, ví dụ:SELECT CAST( CAST(N'' AS XML).value( 'xs:base64Binary("LgkoCU0JJAlNCTAJQAkyCUcJIAAJCTIJTQkfCU0JLwk+CQ8JIAA4CT4JJAkgABsJKAlNCWQJ")' , 'VARBINARY(MAX)' ) AS NVARCHAR(MAX) ) UnicodeEncoding ;
Luôn luôn học

7
Bởi vì đôi khi mọi người cần hoàn thành một số thứ nhất định trong phần mềm vì những lý do bạn không thể luôn dự đoán ...?
đồng bóng

87

Cách đơn giản nhất và ngắn nhất tôi có thể tìm thấy cho SQL Server 2012 trở lên là BINARY BASE64:

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

Cho Base64 thành chuỗi

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

(hoặc nvarchar(max)cho chuỗi Unicode)


1
Điều này đơn giản hơn nhiều so với các câu trả lời khác và cũng hoạt động tốt
sXe

2
mục đích của BINary BASE64 trong dòng đầu tiên là gì? Có cần thiết không? Tôi đã thử mà không có và nó dường như cho kết quả tương tự.
mattpm

1
Đoạn trích đầu tiên cho tôi một kết quả khác so với tôi mong đợi; Tôi đã thay đổi "varbinary" thành "varbinary (max)" và các ký tự bị mất đã rơi vào vị trí
Hraefn

3
Đây phải là câu trả lời vì câu trả lời thực tế đòi hỏi phải có chuỗi ký tự và không thể chấp nhận các biến như câu trả lời này có thể.
Matthew

2
Đối với chuỗi 64 đến chuỗi, tôi nhận thấy mức tăng hoàn hảo đáng kể với .value ('data [1]', 'varbinary (max)') vice .value ('.', 'Varbinary (max)').
Geary M. McIver

25

Đây là một sửa đổi cho câu trả lời của mercurial sử dụng truy vấn con trên giải mã, cho phép sử dụng các biến trong cả hai trường hợp.

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

Đây là mã cho các chức năng sẽ làm việc

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

Ví dụ về cách sử dụng:

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

nhập mô tả hình ảnh ở đây


Nói chung là hữu ích. Điều này đã không xử lý bất kỳ nhân vật như Ba Tư và Nga, hoặc biểu tượng cảm xúc. ví dụ, سلام جیران hoặc В России Base64 кодирует вас hoặc ❤️💥🤪🦌🎅⛄🎄🤐🙈🙉🙊💩
Hunter-Orionnoir

Bạn đúng. Nó xử lý sau khi thay thế varchar thành nvarchar
Oleg

8

Tôi yêu câu trả lời của @ Slai. Tôi chỉ phải thực hiện những sửa đổi rất nhỏ trong một lớp lót mà tôi đang tìm kiếm. Tôi nghĩ tôi sẽ chia sẻ những gì tôi đã kết thúc trong trường hợp nó giúp bất kỳ ai khác tình cờ vào trang này như tôi đã làm:

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]

Đối với tôi, tôi cần thay đổi dòng thứ hai VARBINARYthành VARBINARY(56), và sau đó nó hoạt động.
Lee Grissom

Giải pháp ngắn nhất, tương thích 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]

Điều này là hữu ích cho mã hóa và giải mã.

Bởi Bharat J


0

Tôi đã thực hiện một tập lệnh để chuyển đổi một hàm băm hiện có được mã hóa thành base64 sang số thập phân, nó có thể hữu ích:

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

-1

Bạn chỉ có thể sử dụng:

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

sau đó, sau khi mã hóa, bạn sẽ nhận được văn bản 'MjE4Nqk5'

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.