преобразование в Base64 кодировку

Тема в разделе "LANGS.C", создана пользователем Keva, 17 апр 2007.

  1. Keva

    Keva New Member

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    130
    Подскажите пожалуйста ка преобразовать содержимое переменной BYTE *Variable в Base64 кодировку?
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    http://en.wikipedia.org/wiki/Base64
     
  3. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    вот когда-то писал, мож пригодится
    Код (Text):
    1. .486
    2. .model flat, stdcall
    3. option casemap: none
    4.  
    5. include windows.inc
    6.  
    7. include kernel32.inc
    8. includelib kernel32.lib
    9.  
    10. .data?
    11.     buf     db 256 dup (?)
    12.     buf2        db 1024 dup (?)
    13. .data
    14.  
    15.     alphabet    db 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
    16.     ALPHABET_LEN equ $-alphabet
    17.     pad     db '='
    18.     sBase64     db  'TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0',\
    19.                 'aGlzIHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1',\
    20.                 'c3Qgb2YgdGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0',\
    21.                 'aGUgY29udGludWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdl',\
    22.                 'LCBleGNlZWRzIHRoZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4='
    23. .code
    24.  
    25. base64encode proto szSource:DWORD,szOut:DWORD, sAphabet:DWORD
    26. ;ret eax = size Out
    27. base64encode proc uses esi edi ebx, szSource:DWORD, szOut:DWORD, sAlphabet:DWORD
    28. ;szOut > szSource на 30% + 1b
    29.     LOCAL pMem: DWORD
    30.     LOCAL nMem: DWORD
    31.  
    32.    
    33.     invoke lstrlen, szSource
    34.     mov ebx, eax
    35.     xor edx, edx
    36.     mov ecx, 3
    37.     div ecx
    38.     .if edx != 0
    39.         push ebx
    40.         or ebx, 3  
    41.         mov nMem, ebx
    42.         pop ebx
    43.        
    44.         invoke VirtualAlloc, 0, nMem, MEM_COMMIT, PAGE_READWRITE
    45.         mov pMem, eax
    46.         invoke lstrcpy, pMem, szSource
    47.         mov edi, pMem
    48.         add edi, ebx
    49.         mov ecx, nMem
    50.         sub ecx, ebx
    51.         cld
    52.         mov al, 0
    53.         rep stosb
    54.         mov esi, pMem
    55.     .elseif
    56.         mov esi, szSource
    57.     .endif
    58.     mov edi, szOut
    59.     mov ebx, sAlphabet
    60.     xor edx,edx
    61.     .repeat
    62.         lodsb
    63.         .if al==0
    64.             .break
    65.         .endif
    66.         mov ah, al
    67.         and ah, 11b
    68.         and al, 011111100b
    69.         shr al, 2
    70.         mov dl, al
    71.         mov al, [ebx+edx]
    72.         stosb
    73.        
    74.         lodsb
    75.         and al, 011110000b
    76.         shr al, 4
    77.         shl ah, 4
    78.         or al,ah
    79.         mov dl, al
    80.         mov al, [ebx+edx]
    81.         stosb
    82.         mov ah,[esi-1]
    83.         and ah, 01111b
    84.        
    85.         lodsb
    86.         and al, 011000000b
    87.         shr al, 6
    88.         shl ah, 2
    89.         or al, ah
    90.         mov dl, al
    91.         mov al, [ebx+edx]
    92.         stosb
    93.        
    94.         mov dl, [esi-1]
    95.         and dl, 0111111b
    96.         mov al, [ebx+edx]
    97.         stosb
    98.    
    99.     .until FALSE
    100.     mov al, '='
    101.     stosb
    102.    
    103.     .if pMem != 0
    104.         invoke VirtualFree, pMem, 0, MEM_RELEASE
    105.     .endif
    106.     mov eax, szOut
    107.     sub edi, eax
    108.     mov eax, edi    
    109.    
    110.      
    111.     ret
    112.  
    113. base64encode endp
    114.  
    115.  
    116. ;in: al = alphabet char
    117. ;out: al = alphabet char's index
    118. base64getindex proto sAlphabet:DWORD
    119. base64getindex proc uses edi ecx, sAlphabet:DWORD
    120.  
    121.     mov edi, sAlphabet
    122.     mov ecx, ALPHABET_LEN+1
    123.     repne scasb
    124.     .if ecx==0
    125.         invoke ExitProcess,0
    126.     .endif
    127.     mov eax, ALPHABET_LEN+1
    128.     sub eax, ecx
    129.     dec eax
    130.     ret
    131.        
    132. base64getindex endp
    133.  
    134. base64decode proto  szSource:DWORD, szOut:DWORD, sAlphabet:DWORD
    135.  
    136. base64decode proc uses esi edi ebx, szSource:DWORD, szOut:DWORD, sAlphabet:DWORD
    137.    
    138.     mov esi, szSource
    139.     mov edi, szOut
    140.     mov edx, sAlphabet
    141.     cld
    142.     xor eax, eax
    143.     .repeat
    144.         lodsb
    145.         .if al=='='
    146.             .break
    147.         .endif
    148.         invoke base64getindex, edx
    149.         mov bh, al
    150.         shl bh, 2
    151.        
    152.         lodsb
    153.         invoke base64getindex, edx
    154.         mov bl, al
    155.         and al, 110000b
    156.         shr al, 4
    157.         or al, bh
    158.         and bl, 01111b
    159.         shl bl, 4
    160.         mov bh, bl
    161.         stosb
    162.        
    163.         lodsb
    164.         invoke base64getindex, edx
    165.         mov bl, al
    166.         and al, 111100b
    167.         shr al, 2
    168.         or al, bh
    169.         and bl, 11b
    170.         shl bl, 6
    171.         mov bh, bl
    172.         stosb
    173.        
    174.         lodsb
    175.         invoke base64getindex, edx
    176.         or al, bh
    177.         stosb
    178.    
    179.     .until FALSE
    180.     mov al, 0
    181.     stosb
    182.     invoke lstrlen, szOut
    183.    
    184.     ret
    185.  
    186. base64decode endp
    187.  
    188.  
    189. start:
    190.    
    191.     invoke base64decode, offset sBase64, offset buf2, offset alphabet
    192.     ret
    193.  
    194. end start
    вроде работает, хотя koderr показывал более элегантный код :)
     
  4. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Интересный код. Спасибо! Однако, не внедряясь в самые дебри хотелось бы (давно уже хотелось бы :)) уточнить: этот код кодирует данные, размер которых кратен 3-м. Ведь так? А что делать, если, скажем, длина данных 8 байт, а не 9? В этом случае надо представить, 2 символа - по "6 бит", и один - "4 бита"? Или я не прав?
     
  5. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    ой, я вспомнил тот код что был малость бажный, я после того его обновлял, обновил предидущий пост.
    MSoft
    прав, недостающие биты принимаются равными 0
    вот "тута" проверяется входной буфер на кратность 3 и принимаются и добавляются нужные нулевые биты.
    Код (Text):
    1. invoke lstrlen, szSource
    2.     mov ebx, eax
    3.     xor edx, edx
    4.     mov ecx, 3
    5.     div ecx
    6.     .if edx != 0
    7. ...
    кстати если это применять в своём софте в должности тривиальной шифровки и изменить порядок буков в алфавите можно заставить почесать репу тем кто это отснифает :)
     
  6. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    rain, во-первых, хочу сказать спасибо зо то, что вернул меня к этому коду - давно хотел сесть, но никак руки не доходили :)

    Во-вторых, я сделал немного не так. Может это и не соответствует норме, но, тем не менее, мой код обрабатывает данные любой длины:

    [deleted] код был удален, т.к. делал все наоборот :) Щас чуточку подправлю и выложу

    Я просто разбиваю все данные на блоки по 6 бит. Т.е. получается, если данных было на 4 байта, то в блоках это будет выглядеть так: 5 блоков по 6 бит, а последний блок будет состоять из 2-х бит. Вот этот самый последний блок я обрабатываю как полноценный блок, т.е. тоже ищу ему соответствие в "алфавите" :)

    P.S.: вместо знака "/" я использую знак "-". Функцию раскодирования напишу позже, если убдут заявки :) А щас мультик начинается :)
     
  7. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    выхдит у меня не свовсем правильный base64 :dntknw:
     
  8. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    я ж говорю, я не знаю, соответствует ли это стандарту :) Читать рфц - последнее дело :)
     
  9. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    мультики на первом :)
     
  10. Stub

    Stub New Member

    Публикаций:
    0
    Регистрация:
    11 май 2004
    Сообщения:
    311
    Адрес:
    Siberia
    Смотрите либу от Quantum'а на данном сайте
     
  11. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    не, так не интересно :) Надо самому помучиться :)

    Вобщем, дописал код, исправил ошибки. Вроде бы работаить правильно:
    Код (Text):
    1. ;#####################################################
    2. ;#####################################################
    3. Base64EncodeA proc lpSrc,lpDst:DWORD
    4.     push edi
    5.     mov edi,lpSrc
    6.     xor eax,eax
    7. @@: scasb
    8.     jnz @B
    9.     dec edi
    10.     sub edi,lpSrc
    11.     push edi
    12.     push lpDst
    13.     push lpSrc
    14.     call Base64Encode
    15.     pop edi
    16.     ret
    17. Base64EncodeA endp
    18.  
    19. Base64Encode proc lpSrc,lpDst,dwSize:DWORD
    20.     pushad
    21.     xor eax,eax
    22.     mov esi,lpSrc
    23.     mov edi,lpDst
    24.     mov ecx,dwSize
    25.     jecxz _end
    26.  
    27. _next_dword:
    28.     lodsb
    29.     mov dl,al
    30.     shr al,2                    ;al = первые 6 бит данных
    31.     and dl,11b                  ;ah = оставшиеся 2 бита данных
    32.     call _convert_byte          ;конвертировать и сохранить первый байт
    33.     dec ecx
    34.     jz @F
    35.    
    36.     lodsb
    37. @@: mov ah,al
    38.     shr al,4
    39.     shl dl,4
    40.     or al,dl
    41.     and ah,1111b
    42.     call _convert_byte
    43.     jecxz _end_data
    44.     dec ecx
    45.     jz @F
    46.    
    47.     lodsb
    48. @@: mov dl,ah
    49.     mov ah,al
    50.     shr al,6
    51.     shl dl,2
    52.     or al,dl
    53.     and ah,111111b
    54.     call _convert_byte
    55.     jecxz _end_data
    56.    
    57.     mov al,ah
    58.     call _convert_byte
    59.     dec ecx
    60.     jnz _next_dword
    61.  
    62. _end_data:
    63.     mov ecx,edi
    64.     sub ecx,lpDst
    65.     and ecx,11b                 ;остаток от деления на 4
    66.     jecxz @F
    67.     sub ecx,4
    68.     neg ecx
    69. @@: mov al,'='
    70.     rep stosb
    71.     xor al,al
    72.     stosb
    73.     dec edi
    74.     sub edi,lpDst
    75.     mov eax,edi
    76.  
    77. _end:
    78.     mov [esp+7*4],eax
    79.     popad
    80.     ret
    81.  
    82. _convert_byte:
    83.     mov bh,'A'
    84.     cmp al,25
    85.     jbe @F
    86.     mov bh,'a'-26
    87.     cmp al,51
    88.     jbe @F
    89.     mov bh,'0'-52
    90.     cmp al,61
    91.     jbe @F
    92.     mov bh,'+'-62
    93.     cmp al,62
    94.     jz @F
    95.     ;inc bh                     ;для символа "-"
    96.     mov bh,'/'-63               ;для символа "/"
    97. @@: add al,bh
    98.     stosb
    99.     xor al,al
    100.     retn
    101. Base64Encode endp
    102. ;#####################################################
    103. ;#####################################################
    104. Base64Decode proc lpSrc,lpDst:DWORD
    105.     pushad
    106.     mov esi,lpSrc
    107.     mov edi,lpDst
    108.  
    109. _next_dword:
    110.     lodsb
    111.     or al,al
    112.     jz _end
    113.     cmp al,'='
    114.     jz _end
    115.     call _convert_byte
    116.     mov ah,al
    117.     lodsb
    118.     or al,al
    119.     jz _end                             ;если хоть один 2-х первых из байт блока "неполноценный", тогда дальше не раскодировать
    120.     cmp al,'='
    121.     jz _end
    122.     call _convert_byte                  ;здесь ah - первый раскодированный байт, al - второй
    123.     xchg ah,al
    124.     mov dl,ah
    125.     shr dl,4
    126.     shl al,2
    127.     or al,dl
    128.     shl ah,4
    129.     stosb                               ;сохранить первый раскодированный байт
    130.    
    131.     lodsb
    132.     or al,al
    133.     jz _end
    134.     cmp al,'='
    135.     jz _end
    136.     call _convert_byte
    137.     xchg ah,al
    138.     mov dl,ah
    139.     shr dl,2
    140.     or al,dl
    141.     shl ah,6
    142.     stosb                               ;сохранить второй раскодированный байт
    143.    
    144.     lodsb
    145.     or al,al
    146.     jz _end
    147.     cmp al,'='
    148.     jz _end
    149.     call _convert_byte
    150.     or al,ah
    151.     stosb                               ;сохранить третий раскодированный байт
    152.     jmp _next_dword
    153.    
    154. _end:
    155.     sub edi,lpDst
    156.     mov [esp+7*4],edi
    157.     popad
    158.     ret
    159.  
    160. _convert_byte:
    161.     mov bh,'+'-62
    162.     cmp al,'+'
    163.     jz @F
    164. ;   inc bh                              ;для символа "-"
    165.     mov bh,'/'-63                       ;для символа "/"
    166.     cmp al,'/'
    167.     jz @F
    168.     mov bh,'0'-52
    169.     cmp al,'9'
    170.     jbe @F
    171.     mov bh,'A'
    172.     cmp al,'Z'
    173.     jbe @F
    174.     mov bh,'a'-26
    175. @@: sub al,bh
    176.     retn
    177. Base64Decode endp
    Если кто найдет ошибки, буду крайне признателен
     
  12. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    Base64EncodeA, in = "sur", out = "c3Vy===="
     
  13. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    исправлено

    кстати, справедливости ради стоит заметить, что код Quantum'а действительно меньше моего. Причем намного меньше: функция кодирования у него занимает на 16, а раскодирования - аж на 26 байт меньше.

    Однако позволю себе сделать такое замечание: я попробовал закодировать строку "hello, i am a virus!". В результате и у квантума и у себя получил "aGVsbG8sIGkgYW0gYSB2aXJ1cyE=". Однако при расшивровке, если убрать последний символ, т.е. знак "=", то функция квантума обрезает последние 2 байта, т.е. получается "hello, i am a viru". У меня такого не происходит. Возможно, это как-то связано с диалогом или нулевым символом в конце, но тем не менее такое печальное событие имеет место быть у него :dntknw:
     
  14. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Насколько я знаю base64, обрезать "=" в конце просто некорректно, получится недопустимая с точки зрения декодера строка...
     
  15. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    diamond, ты прав. Но я рассматриваю вариант, когда строка может быть повреждена. Тотже знак "=" в моем примере по сути не играет абсолютно никакой роли, но функция quantum'а это не учитвает. В целом, это конечно же мелочь.
     
  16. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    нет :) на вики утверждается противоположное:
    чтобы протестить код нада прогнать эти 4 варианта )
     
  17. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    Насколько понял я, знак "=" используется только для выравнивания текста по 4 байта. И все, никакой нагрузки он не несет. В правильном коде он конечно же обязан быть, но, т.к. нагрузки он не несет, я счел нужным обработать вариант, когда этого символа в силу определенных причин нет.
     
  18. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    rain
    И где же утверждается противоположное? Строки "c3VyZQ==" и "c3Vy" правильные, а "c3VyZQ=" и "c3VyZQ" - нет.
    MSoft
    Если выравнивающих символов "=" в конце нет, то с ненулевой вероятностью строка повреждена и только нехваткой дело не ограничивается. Впрочем, что именно возвращать на выходе в случае некорректного входа - вопрос, не имеющий особого смысла (главное, не падать :))
     
  19. rain

    rain New Member

    Публикаций:
    0
    Регистрация:
    22 апр 2006
    Сообщения:
    976
    diamond ничё не понял..
    в цитате все строки правильные
     
  20. MSoft

    MSoft New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    2.854
    diamond

    Полностью с тобой согласен. Могу в ответ только сделать рекурсию в виде jmp @17 :))