Мы хотим войти в систему QNAP NAS через API, и поэтому пароль должен быть закодирован. В документации указано, что этот скрипт используется для кодирования: http://eu1.qnap.com/Storage/SDK/get_sid.js
Это похоже на кодировку base64, и я хочу иметь возможность кодировать пароли в C#, так как мы будем вызывать API из написанного C# бэкэнда. Поэтому я попытался проверить кодировку с помощью следующего C# кода:
public static class EncodeHelper
{
private const string EzEncodechars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
public static string Utf16to8(string input)
{
byte[] utf16Bytes = Encoding.Unicode.GetBytes(input);
byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes);
char[] chars = (char[])Array.CreateInstance(typeof(char), utf8Bytes.Length);
for (int i = 0; i < utf8Bytes.Length; i++)
{
chars[i] = BitConverter.ToChar(new byte[2] { utf8Bytes[i], 0 }, 0);
}
return new string(chars);
}
public static string Encode(string input)
{
var utf8Input = Utf16to8(input);
var plainTextBytes = Encoding.UTF8.GetBytes(utf8Input);
return Convert.ToBase64String(plainTextBytes);
}
}
И большинство тестовых случаев дает одинаковый результат. Например: «admin1234» выдает «YWRtaW4xMjM0» как для кода JavaScript, так и для кода C#, а также наш реальный пароль кодируется в одно и то же значение для кода JavaScript и кода C#. Но когда я пытаюсь закодировать эту строку: «äçéè», выходные данные отличаются. JavaScript возвращает "w6TDp8Opw6g =", но C# возвращает "w4PCpMODwqfDg8Kpw4PCqA ==".
Кажется, что функция utf16to8 не является причиной различного вывода: и JavaScript, и C# преобразует "äçéè" в "äçà © è", так что это кажется чем-то другим происходит в методе ToBase64String или GetBytes. Я также пытался кодировать вручную так:
public static string Encode(string input)
{
//var utf8Input = Utf16to8(input);
//var plainTextBytes = Encoding.UTF8.GetBytes(utf8Input);
//return Convert.ToBase64String(plainTextBytes);
var index = 0;
var inputLength = input.Length;
var output = "";
while (index < inputLength)
{
var char1 = input[index++] & 0xff;
if (index == inputLength)
{
output += EzEncodechars[char1 >> 2];
output += EzEncodechars[(char1 & 0x3) << 4];
output += "==";
break;
}
var char2 = input[index++];
if (index == inputLength)
{
output += EzEncodechars[char1 >> 2];
output += EzEncodechars[((char1 & 0x3) << 4) | ((char2 & 0xF0) >> 4)];
output += EzEncodechars[(char2 & 0xF) << 2];
output += "=";
break;
}
var char3 = input[index++];
output += EzEncodechars[char1 >> 2];
output += EzEncodechars[((char1 & 0x3) << 4) | ((char2 & 0xF0) >> 4)];
output += EzEncodechars[((char2 & 0xF) << 2) | ((char3 & 0xC0) >> 6)];
output += EzEncodechars[char3 & 0x3F];
}
return output;
}
Но результат тот же. Мой вопрос: что вызывает разницу в выводе при использовании специальных символов?