Являются ли эти фрагменты кода C # и Python функционально идентичными?

У меня есть немного исходного кода Python, который я хочу воссоздать на C #. Код - это чтение и дешифрование двоичного файла. Я тестировал функцию в существующем файле, и он работает без ошибок; в то время как результирующая строка не искажена или что-то еще, она мне не кажется полезной.

Но это выходит за рамки этого вопроса. Я только хочу знать, правильно ли я перевел функцию на C #, чтобы он выполнял то же, что и в Python.

Код Python:

    filename = os.path.basename(path_and_filename)
    key = 0
    for char in filename:
        key = key + ord(char)
    f = open(path_and_filename, 'rb')
    results = ''
    tick = 1
    while True:
        byte = f.read(2)
        if byte:
            if tick:
                key = key + 2
            else:
                key = key - 2
            tick = not tick
            res = struct.unpack('h', byte)[0] ^ key
            results = results + chr(res)
            continue
        break
    f.close()
    return results

path_and_filename - абсолютный путь к зашифрованному файлу.

Вот код C #, который я написал:

        string path = _path;
        string fileName = _fileName;
        char[] chars = fileName.ToCharArray();
        int key = 0;
        foreach (char c in chars)
        {
            key += c;
        }
        StringBuilder builder = new StringBuilder();


        using (FileStream file = new FileStream(path, FileMode.Open))
        {
            bool tick = true;

            while (true)
            {
                int i = file.ReadByte();
                if (i == -1)
                    break;
                if (tick)
                    key += 2;
                else
                    key -= 2;
                tick = !tick;


                //The next 2 lines are for parsing the short, equivalent(?) to struct.unpack('h', byte)
                i <<= 8;
                i += file.ReadByte();

                i ^= key;
                byte b = (byte)i;
                char c = (char)b;
                builder.Append(c);
            }
        }
        string result = builder.ToString();

Не обращайте внимания на грязность кода. Будут ли эти 2 фрагмента выдавать один и тот же результат на определенный вход?

11 голосов | спросил Hackworth 26 MaramWed, 26 Mar 2014 03:12:27 +04002014-03-26T03:12:27+04:0003 2014, 03:12:27

2 ответа


4

После полубочи я наконец нашел решение. Запуск кода через Iron Python сказал мне, что os.path.basename (path_and_filename) в моем случае возвращает имя файла, как указано в комментариях, а не имя последней папки. Это была первая проблема, поэтому я работал с неправильным ключом.

Вторая проблема заключалась в том, как я читал байты XOR с помощью ключа. По-видимому, распаковка двух байтов, читаемых, меняет порядок на python, поэтому в C # мне также нужно их прочитать в обратном порядке.

Итак, мой код действительно выглядит примерно так:

    string path = _path;
    string filename = _fileName;

    //python os.path.basename()
    char[] chars = filename.ToCharArray();
    int key = 0;
    foreach (char c in chars)
    {
        key += c;
    }

    StringBuilder builder = new StringBuilder();

    using (FileStream file = new FileStream(path + filename, FileMode.Open))
    {
        bool tick = true;

        while (true)
        {
            int i = file.ReadByte();
            //it's ok to break here because if the first byte is present, then the second byte will also be present, because the data files are well formed.
            if (i == -1)
                break;
            //we can skip the 2nd byte because the algorithm ignores it anyway
            file.ReadByte();

            if (tick)
                key += 2;
            else
                key -= 2;
            tick = !tick;

            i ^= key;

            char c = (char)(i & 255);
            builder.Append(c);
        }
    }
    string result = builder.ToString();
ответил Hackworth 26 MarpmWed, 26 Mar 2014 12:39:31 +04002014-03-26T12:39:31+04:0012 2014, 12:39:31
4

Этот раздел кажется неправильным:

//The next 2 lines are for parsing the short, equivalent(?) to struct.unpack('h', byte)
i <<= 8;
i += file.ReadByte();

вы меняете значение в i 8 бит слева, а затем читаете другой байт. Я предполагаю, что исходный код читал его по 2 байта за раз. Если ваш файл не соответствует длине, то это сломает его здесь. как насчет:

i <<= 8;
int secondByte = file.ReadByte()
if(secondByte != -1)
{
   i += secondByte ;
}

Что с этим? Он отличает int к байту символу, и он усекает.

byte b = (byte)i;
char c = (char)b;

, так что вам лучше игнорировать первый байт и вместо этого все после tick = !tick; может быть:

i = file.ReadByte();

char c = (char)(i ^ (key & 255));
builder.Append(c);

В Python chr() генерирует исключение, если значение больше 255.

И ИМХО, это плохая идея, чтобы свернуть свое собственное шифрование /дешифрование. Вместо этого используйте надежное известное решение .

Вопрос: Я только хочу знать, правильно ли я перевел функцию на C #, чтобы она выполнялась так же, как в Python

Отвечать . Это скорее транслитерация, чем перевод, но они должны давать одинаковый результат. Если бы я переписывал python в c #, он выглядел бы иначе, поскольку мне кажется неэффективным.

ответил James Khoury 26 MaramWed, 26 Mar 2014 06:16:39 +04002014-03-26T06:16:39+04:0006 2014, 06:16:39

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132