Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Кодирование файла алгоритмом XTEA 
:(
    Опции темы
Yogurt
Дата 9.8.2011, 09:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 27.8.2009

Репутация: нет
Всего: нет



Имеется файл txt, в нём храниться определённая информация. Я использую симметричный алгоритм XTEA для кодирования его (encyphier), а затем для рас кодирования. Мой код:

Код

typedef unsigned int uint32_t

void OnBnClickedButtonEncipher()
{
    // v — исходный текст состоящий из двух слов по 32 бита
    // k — ключ состоящий из четырех 32-битных слов
    // num_rounds — число циклов алгоритма (рекомендуется 32)
    // num_rounds должно быть одинаковым для шифрования и расшифрования, если num_rounds==0 то ни шифрования, ни расшифрования происходить не будет

    unsigned int num_rounds = 32;
    uint32_t *v = new uint32_t();

    uint32_t *k = new uint32_t();

    k[0] = 1010101010;
    k[1] = 1010101010;
    k[2] = 1010101010;
    k[3] = 1010101010;
    k[4] = 1010101010;
    k[5] = 1010101010;
    k[6] = 1010101010;
    k[7] = 1010101010;
    
    CStdioFile OFile, IFile;
    int Type;
    #ifdef _UNICODE
        Type = CFile::typeBinary;
    #else
        CFile::typeText;
    #endif

    OFile.Open(L"IFDMU_v300.txt", Type | CFile::modeRead);
    IFile.Open(L"IFDMU_v300_new123.txt", Type | CFile::modeCreate | CFile::modeWrite);

    ULONGLONG ByteLength = OFile.GetLength(); // байт
    
    uint32_t ui_1;
    uint32_t ui_2;

    CString mode = L"";
    int i = 0;
    for(int j = 0; i < ByteLength/8; i++, j = j + 2)
    {
        OFile.Read(&ui_1, sizeof(uint32_t));
        OFile.Read(&ui_2, sizeof(uint32_t));
        
        v[0] = ui_1;
        v[1] = ui_2;
        uint32_t* v_new = xtea3_encipher(num_rounds, v, k);
        
        IFile.Write( &v_new[0], sizeof(uint32_t));
        IFile.Write( &v_new[1], sizeof(uint32_t));
    }

    OFile.Close();
    IFile.Close();
}

uint32_t* xtea3_encipher(unsigned int num_rounds,uint32_t *v, uint32_t *k) 
{
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    for (i=0; i < num_rounds; i++) 
    {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
    }

    v[0]=v0;
    v[1]=v1;
    return v;
}

void OnBnClickedButtonDecipher()
{
    unsigned int num_rounds = 32;
    uint32_t *v = new uint32_t();

    uint32_t *k = new uint32_t();

    k[0] = 1010101010;
    k[1] = 1010101010;
    k[2] = 1010101010;
    k[3] = 1010101010;
    k[4] = 1010101010;
    k[5] = 1010101010;
    k[6] = 1010101010;
    k[7] = 1010101010;
    
    CStdioFile OFile, IFile;
    int Type;
    #ifdef _UNICODE
        Type = CFile::typeBinary;
    #else
        CFile::typeText;
    #endif

    OFile.Open(L"IFDMU_v300_new123.txt", Type | CFile::modeRead);
    IFile.Open(L"IFDMU_v300_new12345.txt", Type | CFile::modeCreate | CFile::modeWrite);

    ULONGLONG ByteLength = OFile.GetLength(); // байт
    
    uint32_t ui_1;
    uint32_t ui_2;

    CString mode = L"";
    int i = 0;
    for(int j = 0; i < ByteLength/8; i++, j = j + 2)
    {
        OFile.Read(&ui_1, sizeof(uint32_t));
        OFile.Read(&ui_2, sizeof(uint32_t));
        
        v[0] = ui_1;
        v[1] = ui_2;
        uint32_t* v_new = xtea2_decipher(num_rounds, v, k);
        
        IFile.Write( &v_new[0], sizeof(uint32_t));
        IFile.Write( &v_new[1], sizeof(uint32_t));
    }

    OFile.Close();
    IFile.Close();
}

uint32_t* xtea2_decipher(unsigned int num_rounds,uint32_t *v, uint32_t *k)
{
    unsigned int i;
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (i=0; i < num_rounds; i++) 
    {
        v1 = v1 - (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        sum = sum - delta;
        v0 = v0 - (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
    }

        v[0]=v0;
    v[1]=v1;
    return v;
}


При кодирование, а затем рас кодирование исходной информации не получается. 
Где ошибка, или что я делаю не так?
PM MAIL   Вверх
Earnest
Дата 9.8.2011, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Yogurt, есть такая штука, "отладчик" называется. Кроме того, у тебя текстовый файл, так что посмотреть, что в нем, просто. 
Вычислительные алгоритмы отлаживаются так: сначала хорошо понимаешь алгоритм, затем вручную  просчитываешь несложный пример, затем сравниваешь ручные вычисления с программой. И находишь ошибку.


--------------------
...
PM   Вверх
borisbn
Дата 9.8.2011, 10:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

Репутация: 22
Всего: 135



Цитата(Yogurt @  9.8.2011,  09:16 Найти цитируемый пост)

    uint32_t *v = new uint32_t();
    uint32_t *k = new uint32_t();

ты выделил по одному 32-х битному слову для v и для k, а пишешь/читаешь по-многу

Цитата(Yogurt @  9.8.2011,  09:16 Найти цитируемый пост)

k[0] = 1010101010;    
k[1] = 1010101010;    
k[2] = 1010101010;    
k[3] = 1010101010;    
k[4] = 1010101010;    
k[5] = 1010101010;    
k[6] = 1010101010;    
k[7] = 1010101010;

Цитата(Yogurt @  9.8.2011,  09:16 Найти цитируемый пост)

v[0] = ui_1;
v[1] = ui_2;


сделай проще:
Код

uint32_t v[ 2 ];
uint32_t k[ 8 ];


Добавлено через 8 минут и 19 секунд
а сам алгоритм рабочий:
http://liveworkspace.org/code/8f94a6f77784...b0166966f597ede


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
Yogurt
Дата 9.8.2011, 16:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 27.8.2009

Репутация: нет
Всего: нет



Спасибо Earnest и borisbn
Проблема возникла ещё с тем, что у меня Юникод, и я забыл, что в Юникодовом тексте первые 2 байта это 0xFEFF.
Выкладываю текст рабочей программы
Остаётся вопрос, почему когда я писал 
Код

...
v1 = v1 - (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
...

программа работала неверное, а когда исправил на 
Код

...
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
...

Все заработало правильно

Собственно, код:
Код

void CCryptography::OnBnClickedButtonEncipher()
{
    // v — исходный текст состоящий из двух слов по 32 бита
    // k — ключ состоящий из четырех 32-битных слов
    // num_rounds — число циклов алгоритма (рекомендуется 32)
    // num_rounds должно быть одинаковым для шифрования и расшифрования, если num_rounds==0 то ни шифрования, ни расшифрования происходить не будет

    unsigned int num_rounds = 32;
    uint32_t k[8] = {1,1,1,1,1,1,1,1};
    uint32_t v[2];

    CStdioFile OFile, IFile;
    int Type;
    #ifdef _UNICODE
        Type = CFile::typeBinary;
    #else
        CFile::typeText;
    #endif

    OFile.Open(L"1.txt", Type | CFile::modeRead);
    IFile.Open(L"2.txt", Type | CFile::modeCreate | CFile::modeWrite);

    #ifdef _UNICODE
    OFile.Seek(2, CFile::begin);
    #endif

    IFile.SeekToBegin();
    WORD BOM = 0xFEFF;
    IFile.Write(&BOM, sizeof(BOM));

    ULONGLONG ByteLength = OFile.GetLength(); // байт
    
    uint32_t ui_1;
    uint32_t ui_2;

    CString mode = L"";
    int i = 0;
    for(int j = 0; i < (ByteLength - 2)/8; i++, j = j + 2)
    {
        OFile.Read(&ui_1, sizeof(uint32_t));
        OFile.Read(&ui_2, sizeof(uint32_t));
        
        v[0] = ui_1;
        v[1] = ui_2;

        xtea3_encipher(num_rounds, v, k);

        IFile.Write( &v[0], sizeof(uint32_t));
        IFile.Write( &v[1], sizeof(uint32_t));
    }

    if((ByteLength - 2)%8 != 0)
    {
        BYTE b1;
        for(int i = 0; i < (ByteLength - 2)%8; i++)
        {
            OFile.Read( &b1, sizeof(b1));
            IFile.Write( &b1, sizeof(b1));
        }
    }

    OFile.Close();
    IFile.Close();
}

void CCryptography::xtea3_encipher(unsigned int num_rounds,uint32_t *v, uint32_t *k)
{
    uint32_t v0=v[0], v1=v[1], sum=0, delta=0x9E3779B9;
    for (unsigned int i=0; i < num_rounds; i++) 
    {
        v0 += (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
        sum += delta;
        v1 += (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
    }

    v[0]=v0;
    v[1]=v1;
}

void CCryptography::OnBnClickedButtonDecipher()
{
    unsigned int num_rounds = 32;
    uint32_t k[8] = {1,1,1,1,1,1,1,1};
    uint32_t v[2];

    CStdioFile OFile, IFile;
    int Type;
    #ifdef _UNICODE
        Type = CFile::typeBinary;
    #else
        CFile::typeText;
    #endif

    OFile.Open(L"2.txt", Type | CFile::modeRead);
    IFile.Open(L"3.txt", Type | CFile::modeCreate | CFile::modeWrite);

    #ifdef _UNICODE
    OFile.Seek(2, CFile::begin);
    #endif

    IFile.SeekToBegin();
    WORD BOM = 0xFEFF;
    IFile.Write(&BOM, sizeof(BOM));

    ULONGLONG ByteLength = OFile.GetLength(); // байт
    
    uint32_t ui_1;
    uint32_t ui_2;

    CString mode = L"";
    int i = 0;
    for(int j = 0; i < (ByteLength - 2)/8; i++, j = j + 2)
    {
        OFile.Read(&ui_1, sizeof(uint32_t));
        OFile.Read(&ui_2, sizeof(uint32_t));
        
        v[0] = ui_1;
        v[1] = ui_2;

        xtea2_decipher(num_rounds, v, k);
        
        IFile.Write( &v[0], sizeof(uint32_t));
        IFile.Write( &v[1], sizeof(uint32_t));
    }

    if((ByteLength - 2)%8 != 0)
    {
        BYTE b1;
        for(int i = 0; i < (ByteLength - 2)%8; i++)
        {
            OFile.Read( &b1, sizeof(b1));
            IFile.Write( &b1, sizeof(b1));
        }
    }

    OFile.Close();
    IFile.Close();
}

void CCryptography::xtea2_decipher(unsigned int num_rounds,uint32_t *v, uint32_t *k)
{
    uint32_t v0=v[0], v1=v[1], delta=0x9E3779B9, sum=delta*num_rounds;
    for (unsigned int i=0; i < num_rounds; i++) 
    {
        v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
        sum -= delta;
        v0 -= (((v1 << 4) ^ (v1 >> 5)) + v1) ^ (sum + k[sum & 3]);
    }

    v[0]=v0;
    v[1]=v1;
}

PM MAIL   Вверх
bsa
Дата 9.8.2011, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Цитата(Yogurt @ 9.8.2011,  16:36)
Остаётся вопрос, почему когда я писал 
Код

...
v1 = v1 - (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
...

программа работала неверное, а когда исправил на 
Код

...
v1 -= (((v0 << 4) ^ (v0 >> 5)) + v0) ^ (sum + k[(sum>>11) & 3]);
...

Все заработало правильно

Потому что приоритет операции "вычитание" выше, чем "побитовое исключающее ИЛИ"
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.1109 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.