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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Декодирование base64 на основании словаря, помогите понять чужой алгоритм 
V
    Опции темы
null56
Дата 4.3.2010, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Всем привет
Разбираюсь с base64, понял его суть и принцип работы, но не могу понять, ЧТО, а главное КАК автор использует для своих целей словарь
Вот пример (не мой, со ссылок википедии)
Исходный словарь, для кодирования байтов
Код

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; // длина 64 символа

И вот что - то зверское, созданное автором для каких целей, я так и не понял
Код

static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; // длина 80 символов

Вот его код использования
Код

    unsigned char in[4], out[3], v;
    int i, len;

    while( !feof( infile ) ) {
        for( len = 0, i = 0; i < 4 && !feof( infile ); i++ ) {
            v = 0;
            while( !feof( infile ) && v == 0 ) {
                v = (unsigned char) getc( infile );
                v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); // ТУТ проверка на то, чтобы символ был в диапозоне массива кодирования cb64 и тут же обращение к загадочному cd64
                if( v ) {
                    v = (unsigned char) ((v == '$') ? 0 : v - 61);  // 61 - это код символа суффикса (=)
                }
            }
            if( !feof( infile ) ) {
                len++;
                if( v ) {
                    in[ i ] = (unsigned char) (v - 1); // я даже не доходил до этого места, потому что не ясность появляется намного раньше
                }
            }
            else {
                in[i] = 0;
            }
        }
        if( len ) {
            decodeblock( in, out );
            for( i = 0; i < len - 1; i++ ) {
                putc( out[i], outfile );
            }
        }


функция decodeblock, уже формирует из 4 байтов 3, там всё понятно, но вот что происходит
Код

v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); // ТУТ
//...
v = (unsigned char) ((v == '$') ? 0 : v - 61);  // ТУТ
// и тут
in[ i ] = (unsigned char) (v - 1);


Вопрос:
что за хитрый алгоритм использует автор алгоритма и как надо формировать этот интересный массив cd64, если допустим я захочу (а мне и надо) изменить пару символов в исходном словаре

Заранее благодарен за помощь

Добавлено через 10 минут и 3 секунды
вообще мысли у меня уже в кучу, но подозрение на то, что загадочный массив cd64 - это массив кодов значений, которые были получены из 6 битовых значений входных байтов, при енкодинге

Это сообщение отредактировал(а) null56 - 4.3.2010, 00:35
PM MAIL   Вверх
GoldFinch
Дата 4.3.2010, 14:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


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

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



проще написать самому с нуля
PM MAIL ICQ   Вверх
null56
Дата 5.3.2010, 16:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Разобрался я в алгоритме автора по ходу реализации своего
Еще раз, в чем суть алгоритма base64
Encoding:
1) Вытащить 3 байта и сделать из них 4, посредством вытаскивания 6 битов... всё верно 3 байта * 8 = 24 бита, а 24 / 6 = 4 (6 битовых значения)
2) Использовать полученные 6 битовые значения, как индексы в алфавите ниже, значения могут быть [0..63]
Код

static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

Возьмем последовательсность: 65, 66, 67 (A,B,C).
- двоичное представление: 01000001 (65), 01000010 (66), 01000011 (67) 
- вытащим 4 шестибитовых значений: 010000 (16), 010100 (20), 001001 (9), 000011(3)
- используем эти шестибитовые значения в качестве индексов в алфавите: Q(16), U(20), J(9), D(3) - это выходная последовательность, то есть выходной base64
- но ведь в выходной последовательсности у нас уже не 16, 20, 9, 3, а коды цифр алвавита: 81(Q), 85(U), 74(J), 68(D), то есть просто так мы не вернемся, нам нужна таблица соответсвий реальных индексов, которая была на шаге раньше, где:
['А'] - 0
['B'] - 1
.......
['+'] - 62
['/'] - 63
в кодовом представлении это будет выглядеть так
[65] - 0
[66] - 1
[67] - 2
............
[43] - 62
[47] - 63
реализация
Код

#define B64(_)    ((_) == 'A' ? 0        \
    : (_) == 'B' ? 1                \
    : (_) == 'C' ? 2                \
    : (_) == 'D' ? 3                \
    : (_) == 'E' ? 4                \
    : (_) == 'F' ? 5                \
    : (_) == 'G' ? 6                \
    : (_) == 'H' ? 7                \
    : (_) == 'I' ? 8                \
    : (_) == 'J' ? 9                \
    : (_) == 'K' ? 10                \
    : (_) == 'L' ? 11                \
    : (_) == 'M' ? 12                \
    : (_) == 'N' ? 13                \
    : (_) == 'O' ? 14                \
    : (_) == 'P' ? 15                \
    : (_) == 'Q' ? 16                \
    : (_) == 'R' ? 17                \
    : (_) == 'S' ? 18                \
    : (_) == 'T' ? 19                \
    : (_) == 'U' ? 20                \
    : (_) == 'V' ? 21                \
    : (_) == 'W' ? 22                \
    : (_) == 'X' ? 23                \
    : (_) == 'Y' ? 24                \
    : (_) == 'Z' ? 25                \
    : (_) == 'a' ? 26                \
    : (_) == 'b' ? 27                \
    : (_) == 'c' ? 28                \
    : (_) == 'd' ? 29                \
    : (_) == 'e' ? 30                \
    : (_) == 'f' ? 31                \
    : (_) == 'g' ? 32                \
    : (_) == 'h' ? 33                \
    : (_) == 'i' ? 34                \
    : (_) == 'j' ? 35                \
    : (_) == 'k' ? 36                \
    : (_) == 'l' ? 37                \
    : (_) == 'm' ? 38                \
    : (_) == 'n' ? 39                \
    : (_) == 'o' ? 40                \
    : (_) == 'p' ? 41                \
    : (_) == 'q' ? 42                \
    : (_) == 'r' ? 43                \
    : (_) == 's' ? 44                \
    : (_) == 't' ? 45                \
    : (_) == 'u' ? 46                \
    : (_) == 'v' ? 47                \
    : (_) == 'w' ? 48                \
    : (_) == 'x' ? 49                \
    : (_) == 'y' ? 50                \
    : (_) == 'z' ? 51                \
    : (_) == '0' ? 52                \
    : (_) == '1' ? 53                \
    : (_) == '2' ? 54                \
    : (_) == '3' ? 55                \
    : (_) == '4' ? 56                \
    : (_) == '5' ? 57                \
    : (_) == '6' ? 58                \
    : (_) == '7' ? 59                \
    : (_) == '8' ? 60                \
    : (_) == '9' ? 61                \
    : (_) == '+' ? 62                \
    : (_) == '/' ? 63                \
    : -1)

    static const signed char b64[0x100] = {
        B64 (0), B64 (1), B64 (2), B64 (3), B64 (4), B64 (5), B64 (6), B64 (7), B64 (8), B64 (9), B64 (10), B64 (11),
        B64 (12), B64 (13), B64 (14), B64 (15), B64 (16), B64 (17), B64 (18), B64 (19), B64 (20), B64 (21), B64 (22), B64 (23),
        B64 (24), B64 (25), B64 (26), B64 (27), B64 (28), B64 (29), B64 (30), B64 (31), B64 (32), B64 (33), B64 (34), B64 (35),
        B64 (36), B64 (37), B64 (38), B64 (39), B64 (40), B64 (41), B64 (42), B64 (43), B64 (44), B64 (45), B64 (46), B64 (47),
        B64 (48), B64 (49), B64 (50), B64 (51), B64 (52), B64 (53), B64 (54), B64 (55), B64 (56), B64 (57), B64 (58), B64 (59),
        B64 (60), B64 (61), B64 (62), B64 (63), B64 (64), B64 (65), B64 (66), B64 (67), B64 (68), B64 (69), B64 (70), B64 (71),
        B64 (72), B64 (73), B64 (74), B64 (75), B64 (76), B64 (77), B64 (78), B64 (79), B64 (80), B64 (81), B64 (82), B64 (83),
        B64 (84), B64 (85), B64 (86), B64 (87), B64 (88), B64 (89), B64 (90), B64 (91), B64 (92), B64 (93), B64 (94), B64 (95),
        B64 (96), B64 (97), B64 (98), B64 (99), B64 (100), B64 (101), B64 (102), B64 (103), B64 (104), B64 (105), B64 (106), B64 (107),
        B64 (108), B64 (109), B64 (110), B64 (111), B64 (112), B64 (113), B64 (114), B64 (115), B64 (116), B64 (117), B64 (118), B64 (119),
        B64 (120), B64 (121), B64 (122), B64 (123), B64 (124), B64 (125), B64 (126), B64 (127), B64 (128), B64 (129), B64 (130), B64 (131),
        B64 (132), B64 (133), B64 (134), B64 (135), B64 (136), B64 (137), B64 (138), B64 (139), B64 (140), B64 (141), B64 (142), B64 (143),
        B64 (144), B64 (145), B64 (146), B64 (147), B64 (148), B64 (149), B64 (150), B64 (151), B64 (152), B64 (153), B64 (154), B64 (155),
        B64 (156), B64 (157), B64 (158), B64 (159), B64 (160), B64 (161), B64 (162), B64 (163), B64 (164), B64 (165), B64 (166), B64 (167),
        B64 (168), B64 (169), B64 (170), B64 (171), B64 (172), B64 (173), B64 (174), B64 (175), B64 (176), B64 (177), B64 (178), B64 (179),
        B64 (180), B64 (181), B64 (182), B64 (183), B64 (184), B64 (185), B64 (186), B64 (187), B64 (188), B64 (189), B64 (190), B64 (191),
        B64 (192), B64 (193), B64 (194), B64 (195), B64 (196), B64 (197), B64 (198), B64 (199), B64 (200), B64 (201), B64 (202), B64 (203),
        B64 (204), B64 (205), B64 (206), B64 (207), B64 (208), B64 (209), B64 (210), B64 (211), B64 (212), B64 (213), B64 (214), B64 (215),
        B64 (216), B64 (217), B64 (218), B64 (219), B64 (220), B64 (221), B64 (222), B64 (223), B64 (224), B64 (225), B64 (226), B64 (227),
        B64 (228), B64 (229), B64 (230), B64 (231), B64 (232), B64 (233), B64 (234), B64 (235), B64 (236), B64 (237), B64 (238), B64 (239),
        B64 (240), B64 (241), B64 (242), B64 (243), B64 (244), B64 (245), B64 (246), B64 (247), B64 (248), B64 (249), B64 (250), B64 (251),
        B64 (252), B64 (253), B64 (254), B64 (255)
    };

Если сделать вывод полученной последовательности, то имеем (я сделал вывод в три строки, для наглядности), знаком $ помечены символы, которые не входят в алфавит base64
Код

for (int i = 0; i < 255; i++)
{
    if (b64[i] == -1)
    {
        printf("$");
    }
    else
    {
        printf("%d", b64[i]);
    }
}

Цитата

$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
62$$$6352535455565758596061$$$$$$$012345678910111213141516171819202122232425$$$$$$2627282930313233343536373839404142434445464748495051
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

обратив внимание на вторую строку и сравнив ее с созданной автором
Код

static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq";

я обнаружил сходство, начиная с символа 43...
По русски, автор просто не стал использовать все 255 символов, а отбросил всё до 43 и после 122... действительно, зачем они? и таблица у него смещена на 43 символа, это объясняет
Код

v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]);

Далее меня интересовало, зачем автор сделал все символы на 61 кодовое значение меньше.... тут я думаю просто, чтобы их можно было представить в виде строки
Код

v = (unsigned char) ((v == '$') ? 0 : v - 61);

Ну и наконец погрешность индекса
Код

in[ i ] = (unsigned char) (v - 1);


Так что вот такие дела )
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.0637 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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