2017-07-21 53 views
3

我需要的是確保一個字符串以已知的字符編碼進行編碼。到目前爲止,我使用MS SQL Server進行的研究和測試顯示,記錄的編碼是'UCS-2',但實際編碼(在服務器上)是'UCS-2LE'。如何確保Microsoft SQL Server中的特定字符編碼?

這看起來不太可靠。我所喜歡的是PERL,Node或其他任何東西中的ENCODE函數,所以無論升級或設置如何變化,我的散列函數都將處理已知的輸入。

我們可以將散列字符串限制爲十六進制,所以在最壞的情況下,我們可以手動將16個可能的輸入字符映射到正確的字節。任何人都有這方面的建議?

下面是我使用的PERL:它匹配MS SQL

use Digest::SHA qw/sha256/; 
use Encode qw/encode/; 

$seed = 'DDFF5D36-F14D-495D-BAA6-3688786D6CFA'; 
$string = '123456789'; 

$target = '57392CD6A5192B6185C5999EB23D240BB7CEFD26E377D904F6FEF262ED176F97'; 

$encoded = encode('UCS-2LE', $seed.$string); 
$sha256 = uc(unpack("H*", sha256($encoded))); 

print "$target\n$sha256\n"; 

HASHBYTES('SHA_256', 'DDFF5D36-F14D-495D-BAA6-3688786D6CFA123456789') 

但我真正想要的是:

HASHBYTES('SHA_256', ENCODE('UCS2-LE', 'DDFF5D36-F14D-495D-BAA6-3688786D6CFA123456789')) 

所以,無論什麼MS SQL恰好將輸入字符串編碼爲,HASHBYTES將始終在已知的字節數組上運行。

回答

0

SQL Server僅在聲明爲nvarchar的列,變量和文字上使用UCS-2。在所有其他情況下,除非另外指定(例如,使用collate子句),否則它使用8位ASCII與當前數據庫的編碼。

所以,你要麼必須指定Unicode文字:

select HASHBYTES('SHA_256', N'DDFF5D36-F14D-495D-BAA6-3688786D6CFA123456789'); 

或者,你可以使用nvarchar數據類型的變量或表列:

-- Variable 
declare @var nvarchar(128) = N'DDFF5D36-F14D-495D-BAA6-3688786D6CFA123456789'; 

select HASHBYTES('SHA_256', @var); 

-- Table column 
declare @t table(
    Value nvarchar(128) 
); 

insert into @t 
select @var; 

select HASHBYTES('SHA_256', t.Value) 
from @t t; 

附:當然,由於Wintel是一個小端平臺,SQL Server使用與OS /硬件相同的編碼版本。除非SQL Server 2017中會出現新的東西,否則無法在本機中在此Universe中獲得大端代表性。

相關問題