0

我们想通过 API 登录 QNAP NAS,因此需要对密码进行编码。在文档中声明使用此脚本进行编码:http ://eu1.qnap.com/Storage/SDK/get_sid.js

这似乎是一种 base64 编码,我希望能够在 C# 中对密码进行编码,因为我们将从 C# 编写的后端调用 API。所以我尝试使用以下 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”将 JavaScript 代码作为 C# 代码给出“YWRtaW4xMjM0”,并且我们的真实密码对于 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;
    }

但结果是一样的。我的问题是:使用特殊字符时导致输出差异的原因是什么?

4

0 回答 0