кодировка base64 для китайских символов - PullRequest
0 голосов
/ 04 июня 2018

Я использую оба следующих метода для кодирования в базе 64 китайской строки.Проблема в том, что у меня 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]('你好')

Метод 2

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

1 Ответ

0 голосов
/ 04 июня 2018

Вам не хватает N, чтобы пометить строковый литерал как Юникод :

 SELECT N'你好' AS unicode
       ,'你好' AS ASCII

Попробуйте это, чтобы получить 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));
* 1017.* ОБНОВЛЕНИЕ Несколько слов о перекодировании

base64 не кодирует строковое значение, но двоичный шаблон, который система использует для сохранения этой строки в памяти (это действительно для любого типа данных).Битовая последовательность строки отличается с UTF-8, UTF-16, ASCII чем угодно ... И еще хуже, есть BE и LE.

Шаги для получения base64:

  • Получить битовую комбинацию моего значения (строку, дату, картинку, любое значение на самом деле)
  • вычислить base64 для этой битовой комбинации

Шаги для перекодирования:

  • Вычисление оригинального битового шаблона, который скрыт в пределах base64
  • Интерпретироватьбитовый шаблон как оригинальное значение

Самый последний шаг может привести к путанице ... Вы должны точно знать , какое двоичное представление использует система,Вы должны использовать точно того же типа данных с точно той же интерпретацией, чтобы вернуть значения.

Со строками нужно знать, что SQL-сервер работаетс очень ограниченным исходным выбором.

  • Существует NVARCHAR (NCHAR), который является 2-байтовым кодированным юникодом в UCS-2 (почти так же, какutf-16)
  • И есть VARCHAR (CHAR), то есть 1-байтовый кодированный расширенный ASCII .Все нелатинские символы связаны с кодовой страницей в связанном сопоставлении.Но это не UTF-8!
...