Sql server 用于中文字符的base64编码

Sql server 用于中文字符的base64编码,sql-server,tsql,base64,chinese-locale,Sql Server,Tsql,Base64,Chinese Locale,我正在使用以下两种方法在base64中编码一个中文字符串。问题是我的输出是Pz8=,解码后的是? 这有什么问题,我该如何解决 方法1 CREATE FUNCTION [dbo].[base64Encode] (@input VARCHAR(MAX)) RETURNS NVARCHAR(MAX) AS BEGIN DECLARE @output NVARCHAR(MAX), @bits VARBINARY(3), @pos INT SET @pos

我正在使用以下两种方法在base64中编码一个中文字符串。问题是我的输出是
Pz8=
,解码后的是

这有什么问题,我该如何解决

方法1

CREATE FUNCTION [dbo].[base64Encode] (@input VARCHAR(MAX))
RETURNS NVARCHAR(MAX)
AS
BEGIN
    DECLARE @output NVARCHAR(MAX),
        @bits VARBINARY(3),
        @pos INT

    SET @pos = 1
    SET @output = ''

    WHILE @pos <= LEN(@input)
    BEGIN
        SET @bits = CONVERT(VARBINARY(3), SUBSTRING(@input, @pos, 3))
        SET @output = @output + SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', SUBSTRING(@bits, 1, 1) / 4 + 1, 1)
        SET @output = @output + SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', SUBSTRING(@bits, 1, 1) % 4 * 16 + SUBSTRING(@bits, 2, 1) / 16 + 1, 1)
        SET @output = @output + SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', SUBSTRING(@bits, 2, 1) % 16 * 4 + SUBSTRING(@bits, 3, 1) / 64 + 1, 1)
        SET @output = @output + SUBSTRING('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', SUBSTRING(@bits, 3, 1) % 64 + 1, 1)
        SET @pos = @pos + 3
    END

    RETURN (LEFT(@output, LEN(@output) - 3 + LEN(@bits)) + REPLICATE('=', 3 - LEN(@bits)))
END

SELECT [dbo].[base64Encode]('你好')

您缺少将字符串文字标记为unicode的
N

尝试此操作可从您的中文字符中获取
base64
,反之亦然:

SELECT (SELECT CAST(N'你好' AS VARBINARY(MAX)) FOR XML PATH(''),TYPE).value(N'.','nvarchar(max)');
您将获得此
base64
结果:YE99WQ==

这是将
base64
重新转换为原始值的方法

SELECT CAST(CAST('<x>' + 'YE99WQ==' + '</x>' AS XML).value('.','varbinary(max)') AS NVARCHAR(MAX));
选择CAST(CAST('+'YE99WQ=='+''作为XML)。值('.','varbinary(max)')作为NVARCHAR(max));
更新一些关于重新编码的单词
base64
不编码字符串值,但系统用于将该字符串保存在内存中的二进制模式(这实际上对任何数据类型都有效)。字符串的位模式不同于
UTF-8
UTF-16
ASCII
等等。。。更糟糕的是,还有BE和LE

获取
base64
的步骤如下:

  • 获取我的值的位模式(字符串、日期、图片、任何实际值)
  • 计算此位模式的
    base64
重新编码的步骤如下

  • 计算隐藏在
    base64
  • 将位模式解释为原始值
最后一步可能会引起混乱。。。您必须准确地知道系统使用的二进制表示法。您必须使用完全相同的数据类型和完全相同的解释来获取值

对于字符串,我们必须知道,SQL Server在本机上的选择非常有限

  • 还有
    NVARCHAR
    NCHAR
    ),它是
    UCS-2
    风格中的2字节编码unicode(几乎与
    utf-16
    相同)
  • 还有
    VARCHAR
    CHAR
    ),它是1字节编码的扩展ASCII码。所有非拉丁字符都绑定到所连接排序规则内的代码页。但是这不是UTF-8

您缺少将字符串文字标记为unicode的
N

尝试此操作可从您的中文字符中获取
base64
,反之亦然:

SELECT (SELECT CAST(N'你好' AS VARBINARY(MAX)) FOR XML PATH(''),TYPE).value(N'.','nvarchar(max)');
您将获得此
base64
结果:YE99WQ==

这是将
base64
重新转换为原始值的方法

SELECT CAST(CAST('<x>' + 'YE99WQ==' + '</x>' AS XML).value('.','varbinary(max)') AS NVARCHAR(MAX));
选择CAST(CAST('+'YE99WQ=='+''作为XML)。值('.','varbinary(max)')作为NVARCHAR(max));
更新一些关于重新编码的单词
base64
不编码字符串值,但系统用于将该字符串保存在内存中的二进制模式(这实际上对任何数据类型都有效)。字符串的位模式不同于
UTF-8
UTF-16
ASCII
等等。。。更糟糕的是,还有BE和LE

获取
base64
的步骤如下:

  • 获取我的值的位模式(字符串、日期、图片、任何实际值)
  • 计算此位模式的
    base64
重新编码的步骤如下

  • 计算隐藏在
    base64
  • 将位模式解释为原始值
最后一步可能会引起混乱。。。您必须准确地知道系统使用的二进制表示法。您必须使用完全相同的数据类型和完全相同的解释来获取值

对于字符串,我们必须知道,SQL Server在本机上的选择非常有限

  • 还有
    NVARCHAR
    NCHAR
    ),它是
    UCS-2
    风格中的2字节编码unicode(几乎与
    utf-16
    相同)
  • 还有
    VARCHAR
    CHAR
    ),它是1字节编码的扩展ASCII码。所有非拉丁字符都绑定到所连接排序规则内的代码页。但是这不是UTF-8

您的文字字符串是
varchar
,而不是
nvarchar
。使用
N'你好'。如果您尝试
选择'你好',不你好';
您很快就会发现问题所在。您的文本字符串是
varchar
,而不是
nvarchar
。使用
N'你好'。如果您尝试
选择'你好',不你好';你会很快发现问题。我想补充一点,以避免在某些外部应用程序解码值时出现混淆。SQL Server使用UTF-16@lad2025最后一部分不正是这样做的吗?@Shnugo是的,在SQL Server内部一切正常(编码/解码)。但是,如果您在SQL Server中编码并使用例如进行解码,您将得到不同的结果。@lad2025是正确的,如果我尝试用您的系统使用javscript atob()函数对我编码的字符串进行解码,我将无法对其进行解码,因为输出是一个在原始解码字符串的每个字符之间都带有“\u0000”的字符串string@Mark阅读我的更新。每个字符之间的
\u0000
指向一个已写入的2字节字符串,该字符串被读取为1字节字符串。我想补充一点,以避免在某些外部应用程序解码值时出现混淆。SQL Server使用UTF-16@lad2025最后一部分不正是这样做的吗?@Shnugo是的,在SQL Server内部一切正常(编码/解码)。但是,如果您在SQL Server中编码并使用例如进行解码,您将得到不同的结果。@lad2025是正确的,如果我尝试用您的系统使用javscript atob()函数对我编码的字符串进行解码,我将无法对其进行解码,因为输出是一个在原始解码字符串的每个字符之间都带有“\u0000”的字符串string@Mark阅读我的更新。每个字符之间的
\u0000
指向一个已写入的2字节字符串,即