2 месяца назад
История
README.md
libbase64
Библиотека на C
для кодирования и декодирования base64
по умолчанию используется вариант RFC4648
, но имеется возможность задать любой иной вариант алфавита кодирования
Не использует выделения памяти, работает с входным и выходным буферами, кодирует и декодирует данные целиком
Можно использовать не как библиотеку, а просто расположить base64.c
и base64.h
в дереве исходников вашего проекта.
Зависимости
- Заголовки
stdint.h
stddef.h
C
компиляторC99
илиC11
Установка и удаление
Глобально
make
sudo make install
sudo make uninstall
Локально
make
make PREFIX=$HOME/.local install
make PREFIX=$HOME/.local uninstall
Независимо
make
make DESTDIR=$HOME/some_you_dir install
make DESTDIR=$HOME/some_you_dir uninstall
Использование
Минимальный пример кодирования
/* This example code licensed as Public Domain CC0 */
/* https://creativecommons.org/public-domain/cc0/ */
#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 = %d\n",status);
return status;
}
/* out_size > written size, in this case need set '\0' */
out[written] = '\0';
/* show result */
printf("data = %s size = %d\n",out, written);
return 0;
}
make && cc encode.c -o app libbase64.a
./app
data = SGVsbG8gV29ybGQh size = 16
Минимальный пример декодирования
/* This example code licensed as Public Domain CC0 */
/* https://creativecommons.org/public-domain/cc0/ */
#include <stdio.h>
#include <string.h>
#include "base64.h"
int main(int argc, char **argv)
{
/* prepare input */
unsigned char inp[] = "SGVsbG8gV29ybGQh";
size_t inp_size = strlen(inp);
/* prepare ouput */
size_t out_size = inp_size; /* or calculate own*/
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_decode(inp,inp_size,out,out_size,&written,NULL);
if(status != BASE64_SUCCESS)
{
fprintf(stderr,"Error: code = %d\n",status);
return status;
}
/*out_size > written size, in this case need set '\0' */
out[written] = '\0';
/* show result */
printf("data = %s size = %d\n",out, written);
return 0;
}
make && cc encode.c -o app libbase64.a
./app
data = Hello World! size = 12
Пример использования альтернативного кодирования
/* This example code licensed as Public Domain CC0 */
/* https://creativecommons.org/public-domain/cc0/ */
#include <stdio.h>
#include <string.h>
#include "base64.h"
int main(int argc, char **argv)
{
/* create you own base64 */
unsigned char alphabet[] =
"ABCDEFGcdefghijHIJKLMN0123456789*?abkOPQRSTUVWXYZlmnopqrstuvwxyz";
unsigned char endcode = '@';
struct base64 mybase;
int reg_status = base64_register(alphabet,endcode,&mybase);
if(reg_status != BASE64_SUCCESS)
{
fprintf(stderr,"Error: code = %d\n",reg_status);
return reg_status;
}
/* 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,&mybase);
if(status != BASE64_SUCCESS)
{
fprintf(stderr,"Error: code = %d\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;
}
make && cc custom.c -o app libbase64.a
./app
data = KGNV5Gw*Nqxm5GI? size = 16
Различные варианты Base64
существующие в реальности. Этот список не претендует на полноту, есть полные совпадения с rfc4648
.
----------
basename = "rfc4648"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
baename = "rfc1421"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
baename = "rfc2045"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
basename = "freenet"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789~-";
----------
basename = "rfc3548"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
basename = "rfc4880"
endcode = '='
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
basename = "y64"
endcode = '-'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
----------
basename = "rfc1642"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
----------
basename = "xmltoken"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.-";
----------
basename = "xmlname"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_:";
----------
basename = "pident1"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-";
----------
basename = "pident2"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789._";
----------
basename = "rfc3501"
endcode = '\0'
alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,";
На заметку
Кажется всё работает правильно. Потоковый механизм кодирования и декодирования base64
в планах.