在 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));
我正在用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));