2016-05-23 48 views
0

我在JS中編寫客戶端代碼,它應該與我無法修改的第三方c#服務兼容。在javascript中編碼base 64,在c中解碼unicode

該服務提供一個base64 的unicode編碼的字符串(一個JSON), 對於(簡化的)實施例,這是C#代碼的緣故:

var myString = Encoding.Unicode.GetBytes("{\"counter\":0}"); 
var encodedString = Convert.ToBase64String(myString); 

這導致: 「ewAiAGMAbwB1AG4AdABlAHIAIgA6ADAAfQA =」

現在我需要更新的客戶端這個編碼的JSON,並返回其將在本C#代碼進行解碼有效的base64字符串:

byte[] bytes = Convert.FromBase64String(encodedString); 
string decodedString = Encoding.Unicode.GetString(bytes); 

我在網上找到的所有解決方案/示例導致解碼功能輸出無效結果。例如,當使用基本的window.btoa("{\"counter\":1}")導致eyJjb3VudGVyIjoxfQ== ,這反過來,當在c#應用上解碼時,將導致格式異常充其量,或導致總亂碼。

任何想法?

+2

當使用'window.btoa'時,它使用UTF8編碼,當你試圖將它解碼爲Unicode字符串時,它最終會變成亂碼。 C#轉換代碼很有趣,但是如果你沒有提供Unicode輸入,它會在執行'Encoding.Unicode.GetString'時崩潰。在C#代碼中將「Unicode」更改爲「UTF8」會發生什麼? –

+0

爲了清楚起見,Windows(和C#)下的Unicode表示UTF16-LE。你必須弄清楚如何在javascript中獲得一個以UTF-16編碼的字符串。 – roeland

+0

那麼,如果我將它改爲'Encoding.UTF8',那麼解碼工作正常。 但是,如果我將其更改爲'Encoding.UTF16',它會崩潰。問題是我無法控制C#代碼,我需要在JS端弄清楚它 - –

回答

1

正如@roeland提到的,「技巧」是先將字符串編碼爲UTF16-LE,然後將UTF16-LE字符串編碼爲base64。

我已經解決它是通過使用第一字符串轉換爲一個字節數組的方式:

function str2ByteArr(str) { 
    var bytes = []; 

    for (var i = 0; i < str.length; ++i) { 
     bytes.push(str.charCodeAt(i)); 
     bytes.push(0); 
    } 
    return bytes; 
} 

"{\"counter\":0}"結果將是:

[123, 0, 34, 0, 99, 0, 111, 0, 117, 0, 110, 0, 116, 0, 101, 0, 114, 0, 34, 0, 58, 0, 48, 0, 125, 0] 

,然後將數組轉換爲base64:

function arrayBufferToBase64(buffer) { 
    var binary = ''; 
    var bytes = new Uint8Array(buffer); 
    var len = bytes.byteLength; 
    for (var i = 0; i < len; i++) { 
     binary += String.fromCharCode(bytes[i]); 
    } 
    return window.btoa(binary); 
} 

並總結一下:

var byteArr = str2ByteArr(str); 
return arrayBufferToBase64(byteArr); 

結果是:

"ewAiAGMAbwB1AG4AdABlAHIAIgA6ADAAfQA=" 

另一種方式我發現字符串轉換爲字節數組用於 'UTF-8', 'UTF-16BE' 和 'UTF-16LE' 編碼通過使用Text.Encoder在那裏你可以明確選擇的編碼就像這樣:

var textEncoder = new TextEncoder('utf-16le') 
textEncoder.encode("{\"counter\":0}") 

但這不Explorer支持。