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

encode base 64 in javascript, decode unicode in c#

我正在用JS编写客户端代码,应该兼容第三方c#服务,我根本无法修改。

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

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

结果为:"ewAiAGMAbwB1AG4AdABlAHIAIgA6ADAAfQA="

现在我需要在客户端更新这个编码的 JSON 和 return 一个有效的 base64 字符串,它将被这个 C# 代码解码:

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

我在网上找到的所有solutions/examples导致解码函数输出无效结果。 例如,当使用基本 window.btoa("{\"counter\":1}") 时会导致 eyJjb3VudGVyIjoxfQ== 反过来,当在 c# 应用程序上解码时,充其量会导致格式异常,或者导致完全乱码。

有什么想法吗?

正如@roeland 提到的,"trick" 是先将字符串编码为 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}")

但是资源管理器不支持。

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

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);
}

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

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);

此 encodeString 传递给您的控制器。

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

C# 代码:

 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;
            }
        }

最终代码:

解密值:

int id = (int)Convert.ToInt64(Cryptography.base64Decode(orders));