SQL Server 2005 T-SQL'de Base64 kodlaması


124

Bir dizeyi Base64 dizesi olarak kodladığım bir T-SQL sorgusu yazmak istiyorum. Şaşırtıcı bir şekilde, Base64 kodlaması yapmak için herhangi bir yerel T-SQL işlevi bulamıyorum. Yerel bir işlev var mı? Değilse, T-SQL'de Base64 kodlaması yapmanın en iyi yolu nedir?


1
Verilerin neden bir base64 dizesi olarak depolanması gerektiğini sorguluyorum. Http üzerinden base64 kullanmanın iyi bir nedeni vardır, yani ASCII karakter kümesinden başka hiçbir şeyi desteklemeyen (ve tüm verileri metin olarak ele alan) sistemler arasında birlikte çalışabilirliği sağlamasıdır. Bir bayt dizisini temel 64'e ve tersini kolayca dönüştürebilirsiniz, öyleyse neden verileri verimli bir şekilde depolamıyorsunuz? Hatta insanların base64 dizelerini nvarchar sütunlarında sakladıklarını gördüm, bu da varbinary alanının% 275'ini kaplar ve disk, ram, ağ vb. İsrafa yol açar.
The Dag

9
Bu, saklamakla değil, bir base64 dizesi oluşturmakla ilgilidir.
Jacob

Yanıtlar:


187

Bunun zaten yanıtlandığını biliyorum, ancak bunu başarmak için tek satırlık SQL ifadeleri bulmayı kabul ettiğimden daha fazla zaman harcadım, bu yüzden başka birinin de aynı şeyi yapması gerektiğinde bunları burada paylaşacağım:

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

İlk (kodlama) sorguda alt sorgu tarafından oluşturulmuş bir tablo kullanmak zorunda kaldım çünkü orijinal değeri ("TestData") onaltılık dize temsiline ("5465737444617461") bağımsız değişken olarak eklemek için herhangi bir yol bulamadım xs: XQuery deyimindeki hexBinary ().

Umarım bu birine yardımcı olur!


7
Kodlama sırasında xs:base64Binary(sql:column("bin"))( xs:hexBinaryçağrı olmadan ) da çalışır. Harika yardım!
amphetamachine

3
Unicode metnin kodlanmasını desteklemek için, TestData'nın önüne 'N' eklemelisiniz : 'SEÇİN CAST ( N ' TestData 'OLARAK DEĞİŞKEN (MAKS)) Bin OLARAK
SEÇ

Unicode metin için çalışmadı ... SELECT CAST (N '' AS XML) .value ('xs: base64Binary (xs: hexBinary (sql: column ("bin")))', 'VARCHAR (MAX)') Base64Encoding FROM (CAST SEÇİN (N 'मन्त्रीले उल्ट्याए सात छन्।' OLARAK DEĞİŞKEN (MAKS)) AS bin_sql_server_temp;
hsuk

3
@hsuk varchar, Unicode ile uyumlu değil. Bunun yerine nvarchar (maks.) Kullanırsanız iyi çalışır, örneğin:SELECT CAST( CAST(N'' AS XML).value( 'xs:base64Binary("LgkoCU0JJAlNCTAJQAkyCUcJIAAJCTIJTQkfCU0JLwk+CQ8JIAA4CT4JJAkgABsJKAlNCWQJ")' , 'VARBINARY(MAX)' ) AS NVARCHAR(MAX) ) UnicodeEncoding ;
AlwaysLearning

7
Çünkü bazen insanların her zaman tahmin edemeyeceğiniz nedenlerle yazılımda belirli şeyleri başarmaları gerekir ...?
mercurial

87

SQL Server 2012 ve üzeri için bulabildiğim en basit ve en kısa yol şudur BINARY BASE64:

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

Base64'ten dizeye

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

(veya nvarchar(max)Unicode dizeleri için)


1
Bu, diğer yanıtlardan çok daha basit ve aynı şekilde çalışıyor
sXe

3
BINARY BASE64'ün ilk satırdaki amacı nedir? Gerekli mi? Olmadan denedim ve aynı sonucu veriyor gibi görünüyor.
mattpm

1
İlk pasaj bana beklediğimden farklı bir sonuç verdi; "Varbinary" i "değişken (maks)" olarak değiştirdim ve eksik karakterler yerine
oturdu

3
Cevap bu olmalıdır, çünkü gerçek cevap dize değişmezleri gerektirir ve bu cevap gibi değişkenleri kabul edemez.
Matthew

2
Base64'ten dizeye, .value ('data [1]', 'varbinary (max)') vice .value ('.', 'Varbinary (max)') ile önemli bir performans kazancı fark ediyorum.
Geary M.McIver

25

Burada, her iki durumda da değişkenlerin kullanımına izin veren, kod çözmede alt sorguyu kullanan mercurial'ın cevabında bir değişiklik var.

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

İşte işi yapacak fonksiyonların kodu

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

Kullanım örneği:

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

görüntü açıklamasını buraya girin


Genellikle faydalıdır. Bu, Farsça ve Rusça gibi karakterleri veya emoji'leri işlemedi. ör. سلام جیران veya В России Base64 кодирует вас veya ❤️💥🤪🦌🎅⛄🎄🤐🙈🙉🙊💩
Hunter-Orionnoir

Haklısın. Varchar'ı nvarchar olarak değiştirdikten sonra işler
Oleg

8

@ Slai'nin cevabına bayıldım. Sadece aradığım tek gömleklerde çok küçük değişiklikler yapmak zorunda kaldım. Bu sayfaya benim yaptığım gibi tökezleyen başkalarına yardımcı olma ihtimaline karşı elde ettiğim şeyi paylaşacağımı düşündü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]

Benim için ikinci satırı VARBINARYolarak değiştirmem gerekiyordu VARBINARY(56)ve sonra işe yaradı.
Lee Grissom

En kısa çözüm, SQL Server 2005+ uyumlu.
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]

Bu kodlama ve kod çözme için kullanışlıdır.

Bharat J tarafından


0

Base64'te kodlanmış mevcut bir hash'i ondalık sayıya dönüştürmek için bir komut dosyası yaptım, yararlı olabilir:

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

-1

Sadece şunları kullanabilirsiniz:

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

kodlamadan sonra 'MjE4Nqk5' metnini alacaksınız

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.