LINUX.ORG.RU

Кодирование и декодирование base64 на Си

 , , , ,


1

2

Опять наговнокодил крч, кодирование/декодирование + возможность использования своего алфавита.

API

int base64_register(unsigned char * alphabet, unsigned char endcode ,struct base64 * base);

int base64_decode(unsigned char * src, size_t src_size,
                  unsigned char * dst, size_t dst_size, size_t * result_size,struct base64 * vatiant);

int base64_encode(unsigned char * src, size_t src_size,
                  unsigned char * dst, size_t dst_size, size_t * result_size,struct base64 * vatiant);

Пример


#include <stdio.h>
#include <string.h>
#include "base64.h"
int main(int argc, char **argv)
{
    /* prepare input */
    unsigned char inp[] = "Hello World!";
    size_t        inp_size = strlen(inp);
    /* prepare ouput */
    size_t        out_size = inp_size * 1.5; // or ((inp_size / 3) * 4) + 4
    unsigned char out[out_size];
    /* prepare variable to save data len (can ignore it and set NULL) */
    size_t        written = 0;
    /* set data, if last parametr is NULL used RFC4648 base64 alphabet */
    int status = base64_encode(inp,inp_size,out,out_size,&written,NULL);
    if(status != BASE64_SUCCESS)
    {
        fprintf(stderr,"Error: code = %c\n",status);
        return status;
    }
    /*out_size > written size, in this case need set '\0' */
    out[written] = '\0';
    printf("data = %s  size = %d\n",out, written);
    return 0;
}

Негодники

Ковыряясь в коде @mittorn понял что я со своей Lua совсем забыл как на Сишечке что-то делать. Реально тупо всё забыл. В качестве тренировки решил хотя бы переписать вот это с Lua на C. И блин у меня на тупо переписывание лоб в лоб ушло несколько дней. И то, я не уверен, всё ли у меня правильно. Вот так вот, касаемо основных инструментов нужна периодическая практика, иначе вжух и зобыл. Эх, ладна, пойду гематогенку съем.

Вдруг кому надо (перед использованием перекреститься, мало ли что!)
Если что сегодня пятница, так что, чур я в домике 🏠

Перемещено leave из talks

★★★★★

Последнее исправление: LINUX-ORG-RU (всего исправлений: 1)

Как ты умудрился раздуть 20-строчный код на аж целую репу?

Вот энкодер правда тут входная строка фиксированной длины (и у выходной паддинга соответственно нет), но даже если сделать полную поддержку - оно не сильно длиннее будет.

static void b64hash(char *dest, uchar const *hash) {
  char const b64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567
89_-";
  size_t p;
  for(p=0; p<10; p++,dest+=4,hash+=3) {
    dest[0] = b64[hash[0] & 63];
    dest[1] = b64[(hash[0] >> 6) | ((hash[1] & 15) << 2)];
    dest[2] = b64[(hash[1] >> 4) | ((hash[2] & 3) << 4)];
    dest[3] = b64[(hash[2] >> 2) & 63];
  }
  dest[0] = b64[hash[0] & 63];
  dest[1] = b64[(hash[0] >> 6) | ((hash[1] & 15) << 2)];
  dest[2] = b64[(hash[1] >> 4)];
}

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от micronekodesu

Можно, но не всегда конец строки есть, входными данными может быть HTML страница, указатель на данные это смещение в ней до base64 блоба, а длинна то размер блоба, у тебя там просто нет конца строки. У меня это вот так и есть, это при декодировании, а при кодировании входные данные - это всё что угодно, и там нет никаких символов окончания строки по определению.

LINUX-ORG-RU ★★★★★
() автор топика
Ответ на: комментарий от fMad

Если очень хочется то самый простой способ это закодировать в латиницу и транслировать в кирилицу, перед декодирование провести обратное преобразование. Это будет самый простой и надёжный вариант делающий то что хочешь и не требующий менять реализацию. В ином случае есть разные варианты реализации.

Тут всё сводится уже к правилу, какой набор символов разрешено использовать это задаст условие для реализации. И в кириллице алфавит больше, если его не кастрировать это будет не база64 уже =)

А так, по сути символы при кодировании как и их коды отличаются лишь порядковым номером, можно кодировать в смещения, а затем накладывать их на любой набор кодов символов которые находятся в неком гарантированном диапазоне (диапазоне относительно друг друга)

LINUX-ORG-RU ★★★★★
() автор топика