在javascript中编码base 64,在c#中解码unicode

时间:2016-05-23 22:03:30

标签: javascript c# unicode encoding base64

我在JS中编写了一个客户端代码,它应该与我无法修改的第三方c#服务兼容。

该服务提供base64 unicode 编码字符串(JSON), 为了(简化)示例,这是c#代码:

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

导致:" ewAiAGMAbwB1AG4AdABlAHIAIgA6ADAAfQA ="

现在我需要在客户端更新这个编码的JSON,并返回一个有效的base64字符串,该字符串将由这个C#代码解码:

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

我在网上找到的所有解决方案/示例都导致解码功能输出无效结果。 例如,当使用基本window.btoa("{\"counter\":1}")导致eyJjb3VudGVyIjoxfQ==时 反过来,当在c#app上解码时,最多会导致格式异常,或导致完全乱码。

任何想法?

3 个答案:

答案 0 :(得分: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}")

但资源管理器不支持此功能。

答案 1 :(得分:0)

可接受的答案假设高字节始终为0。情况并非总是如此,实际上对私はGoogle翻訳を使用訳を进行编码是行不通的。诀窍是使用此处找到的技术:将字符串转换为UTF16 Little Endian数组时使用How to convert a String to Bytearray

bytes.push(charCode & 0xFF);  // low byte
bytes.push((charCode & 0xFF00) >>> 8); // high byte

完整解决方案:

function base64Encode(str)
{
    var bytes = [];
    for (var i = 0; i < str.length; ++i)
    {
        var charCode = str.charCodeAt(i);
        bytes.push(charCode & 0xFF);
        bytes.push((charCode & 0xFF00) >>> 8);
    }

    var len = bytes.length;
    var buffer = "";
    for (var i = 0; i < len; i++)
    {
        buffer += String.fromCharCode(bytes[i]);
    }

    return window.btoa(buffer);
}

答案 2 :(得分:-1)

下面是用于解码的Java脚本代码:

// here you will have to reference again in the inspector the
// SoundController component from above
[SerializeField] private SoundController _soundController;

// ....

// than whereever you have your code for
// "... plays for a specific image target and it stops when the target is lost ..."
// you add the line like e.g. for letter A
SoundController.CurrentLetter = SoundController.Letter.A;

此encodeString传递给您的控制器。

var Base64 = { _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", encode: function (e) { var t = ""; var n, r, i, s, o, u, a; var f = 0; e = Base64._utf8_encode(e); while (f < e.length) { n = e.charCodeAt(f++); r = e.charCodeAt(f++); i = e.charCodeAt(f++); s = n >> 2; o = (n & 3) << 4 | r >> 4; u = (r & 15) << 2 | i >> 6; a = i & 63; if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) } return t }, decode: function (e) { var t = ""; var n, r, i; var s, o, u, a; var f = 0; e = e.replace(/++[++^A-Za-z0-9+/=]/g, ""); while (f < e.length) { s = this._keyStr.indexOf(e.charAt(f++)); o = this._keyStr.indexOf(e.charAt(f++)); u = this._keyStr.indexOf(e.charAt(f++)); a = this._keyStr.indexOf(e.charAt(f++)); n = s << 2 | o >> 4; r = (o & 15) << 4 | u >> 2; i = (u & 3) << 6 | a; t = t + String.fromCharCode(n); if (u != 64) { t = t + String.fromCharCode(r) } if (a != 64) { t = t + String.fromCharCode(i) } } t = Base64._utf8_decode(t); return t }, _utf8_encode: function (e) { e = e.replace(/\r\n/g, "n"); var t = ""; for (var n = 0; n < e.length; n++) { var r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) { t += String.fromCharCode(r >> 6 | 192); t += String.fromCharCode(r & 63 | 128) } else { t += String.fromCharCode(r >> 12 | 224); t += String.fromCharCode(r >> 6 & 63 | 128); t += String.fromCharCode(r & 63 | 128) } } return t }, _utf8_decode: function (e) { var t = ""; var n = 0; var r = c1 = c2 = 0; while (n < e.length) { r = e.charCodeAt(n); if (r < 128) { t += String.fromCharCode(r); n++ } else if (r > 191 && r < 224) { c2 = e.charCodeAt(n + 1); t += String.fromCharCode((r & 31) << 6 | c2 & 63); n += 2 } else { c2 = e.charCodeAt(n + 1); c3 = e.charCodeAt(n + 2); t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); n += 3 } } return t } }


var id = 7;

var encodeString = Base64.encode(id.toString());

console.log(encodeString);

C#代码:

http://localhost:60362/ProjectManagement/Project/ProjectSettings/MTA=

最终代码:

解密值:

 public static string base64Encode(string sData)
        {
            try
            {
                byte[] encData_byte = new byte[sData.Length];

                encData_byte = System.Text.Encoding.UTF8.GetBytes(sData);

                string encodedData = Convert.ToBase64String(encData_byte);

                return encodedData;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }

        /// <summary>
        /// Method To Decrypt Password
        /// </summary>
        /// <param name="sData"></param>
        /// <returns></returns>
        public static string base64Decode(string sData)
        {
            try
            {
                System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();

                System.Text.Decoder utf8Decode = encoder.GetDecoder();

                byte[] todecode_byte = Convert.FromBase64String(sData);

                int charCount = utf8Decode.GetCharCount(todecode_byte, 0, todecode_byte.Length);

                char[] decoded_char = new char[charCount];

                utf8Decode.GetChars(todecode_byte, 0, todecode_byte.Length, decoded_char, 0);

                string result = new String(decoded_char);

                return result;

            }
            catch (Exception)
            {
                return string.Empty;
            }
        }