From c2eb5e5b3a1646adc65ba1e3fdee30b83fdb7820 Mon Sep 17 00:00:00 2001 From: Gregory Date: Tue, 29 Jan 2019 23:23:04 +0200 Subject: [PATCH] buffer encoding --- Makefile | 18 ++++---- inc/ft_base64.h | 10 ++++- inc/tests.h | 8 +++- src/base64/ft_base64_encode_buffer.c | 27 ++++++++++++ src/base64/ft_base64_fill_buffer.c | 7 ++++ src/base64/ft_base64_init.c | 10 ++++- t/base64_tests.c | 62 +++++++++++++++++++++++++++- t/tests.c | 3 ++ watch.sh | 4 ++ 9 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 src/base64/ft_base64_encode_buffer.c create mode 100644 src/base64/ft_base64_fill_buffer.c create mode 100755 watch.sh diff --git a/Makefile b/Makefile index 7fa21d8c..be36aef6 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,9 @@ SHA_SRC = ft_sha256_init.c \ ft_sha224_final.c \ ft_sha224_digest_string.c -BASE64_SRC = ft_base64_init.c +BASE64_SRC = ft_base64_init.c \ + ft_base64_fill_buffer.c \ + ft_base64_encode_buffer.c SRC = main.c \ ft_ssl_init.c \ @@ -152,15 +154,9 @@ CC := clang # rules -all: $(NAME) - -$(NAME): check $(LIBFT) $(OBJ) +$(NAME): $(LIBFT) $(OBJ) $(CC) $(OBJ) $(LINK_FLAGS) -o $(NAME) -check: $(TEST_BIN) - clear - ./$(TEST_BIN) - $(TEST_BIN): $(LIBFT) $(TEST_OBJ) $(CC) $(TEST_OBJ) $(LINK_FLAGS) -o $(TEST_BIN) @@ -175,6 +171,12 @@ $(OBJ_DIR)%.o: %.c $(LIBFT): $(MAKE) -C $(LIBFT_DIR) +all: $(NAME) + +check: $(TEST_BIN) + clear + ./$(TEST_BIN) + clean: rm -f $(OBJ) rm -f $(TEST_OBJ) diff --git a/inc/ft_base64.h b/inc/ft_base64.h index 1ccdf067..2af0a84e 100644 --- a/inc/ft_base64.h +++ b/inc/ft_base64.h @@ -15,17 +15,23 @@ # include -# define FT_BASE64_BLOCK_SIZE 24 +# define FT_BASE64_BLOCK_SIZE 3 +# define FT_BASE64_CHARS_SIZE 4 +# define FT_BASE64_ALPHABET_LENGTH 64 typedef uint64_t t_byte8; typedef unsigned char t_byte1; typedef struct s_base64_ctx { - t_byte8 block_bit_index; t_byte1 block[FT_BASE64_BLOCK_SIZE]; + t_byte1 alphabet[FT_BASE64_ALPHABET_LENGTH]; + t_byte1 chars[FT_BASE64_CHARS_SIZE]; } t_base64_ctx; void ft_base64_init(t_base64_ctx *ctx); +void ft_base64_fill_buffer( + t_base64_ctx *ctx, t_byte1 *data, t_byte8 size); +void ft_base64_encode_buffer(t_base64_ctx *ctx, t_byte8 len); #endif diff --git a/inc/tests.h b/inc/tests.h index eb64b718..3d2c97f4 100644 --- a/inc/tests.h +++ b/inc/tests.h @@ -15,7 +15,6 @@ # define MUNIT_ENABLE_ASSERT_ALIASES # include "munit.h" -# include "tests_macros.h" /* ** MD5 @@ -72,4 +71,11 @@ MunitResult create_digest_string_sha224(const MunitParameter test_params[], */ MunitResult should_init_base64_ctx(const MunitParameter test_params[], void *test_data); + +MunitResult should_fill_base64_buffer(const MunitParameter test_params[], + void *test_data); + +MunitResult should_clean_base64_buffer(const MunitParameter [], void *); +MunitResult should_encode_base64_buffer(const MunitParameter test_params[], + void *test_data); #endif diff --git a/src/base64/ft_base64_encode_buffer.c b/src/base64/ft_base64_encode_buffer.c new file mode 100644 index 00000000..42a5138b --- /dev/null +++ b/src/base64/ft_base64_encode_buffer.c @@ -0,0 +1,27 @@ +#include "libft.h" +#include "ft_base64.h" + +void ft_base64_encode_buffer(t_base64_ctx *ctx, t_byte8 len) +{ + t_byte1 first_char; + t_byte1 second_char; + t_byte1 third_char; + t_byte1 fourth_char; + + first_char = (ctx->block[0] >> 2) & 0x3f; + second_char = ((ctx->block[0] << 4) & 0x30) | ((ctx->block[1] >> 4) & 0xf); + third_char = ((ctx->block[1] << 2) & 0x3c) | ((ctx->block[2] >> 6) & 0x3); + fourth_char = ctx->block[2] & 0x3F; + + ctx->chars[0] = ctx->alphabet[first_char]; + ctx->chars[1] = ctx->alphabet[second_char]; + if (len < 2) + ctx->chars[2] = '='; + else + ctx->chars[2] = ctx->alphabet[third_char]; + if (len < 3) + ctx->chars[3] = '='; + else + ctx->chars[3] = ctx->alphabet[fourth_char]; + ft_bzero(ctx->block, FT_BASE64_BLOCK_SIZE); +} \ No newline at end of file diff --git a/src/base64/ft_base64_fill_buffer.c b/src/base64/ft_base64_fill_buffer.c new file mode 100644 index 00000000..2e5b2829 --- /dev/null +++ b/src/base64/ft_base64_fill_buffer.c @@ -0,0 +1,7 @@ +#include "libft.h" +#include "ft_base64.h" + +void ft_base64_fill_buffer(t_base64_ctx *ctx, t_byte1 *data, t_byte8 size) +{ + ft_memcpy(ctx->block, data, size); +} \ No newline at end of file diff --git a/src/base64/ft_base64_init.c b/src/base64/ft_base64_init.c index fdc599d0..6eb4dcf8 100644 --- a/src/base64/ft_base64_init.c +++ b/src/base64/ft_base64_init.c @@ -15,6 +15,14 @@ void ft_base64_init(t_base64_ctx *ctx) { - ctx->block_bit_index = 0; + char capital_case[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + char lower_case[] = "abcdefghijklmnopqrstuvwxyz"; + char rest[] = "0123456789+/"; + ft_bzero(ctx->block, FT_BASE64_BLOCK_SIZE); + ft_bzero(ctx->chars, FT_BASE64_CHARS_SIZE); + ft_memcpy(ctx->alphabet, capital_case, 26); + ft_memcpy(ctx->alphabet + 26, lower_case, 26); + ft_memcpy(ctx->alphabet + 52, rest, 12); + } diff --git a/t/base64_tests.c b/t/base64_tests.c index 82808900..158af5d7 100644 --- a/t/base64_tests.c +++ b/t/base64_tests.c @@ -7,12 +7,72 @@ TEST_RESULT should_init_base64_ctx(TEST_PARAMS, TEST_DATA) UNUSED(test_params); UNUSED(test_data); t_base64_ctx ctx; + char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; ft_base64_init(&ctx); - munit_assert_true(ctx.block_bit_index == 0); for (int i = 0; i < FT_BASE64_BLOCK_SIZE; i++) munit_assert_uchar(ctx.block[i], ==, 0); + for (int i = 0; i < FT_BASE64_CHARS_SIZE; i++) + munit_assert_uchar(ctx.chars[i], ==, 0); + + munit_assert_string_equal(alphabet, (char *)ctx.alphabet); + + return MUNIT_OK; +} + +TEST_RESULT should_fill_base64_buffer(TEST_PARAMS, TEST_DATA) +{ + UNUSED(test_params); + UNUSED(test_data); + + t_base64_ctx ctx; + + ft_base64_init(&ctx); + + t_byte1 data[] = "123"; + ft_base64_fill_buffer(&ctx, data, 3); + + munit_assert_memory_equal(3, ctx.block, data); + return MUNIT_OK; +} + +TEST_RESULT should_clean_base64_buffer(TEST_PARAMS, TEST_DATA) +{ + UNUSED(test_params); + UNUSED(test_data); + + t_base64_ctx ctx; + + ft_base64_init(&ctx); + + ft_base64_fill_buffer(&ctx, (t_byte1 *)"Man", 3); + ft_base64_encode_buffer(&ctx, 3); + for (int i = 0; i < FT_BASE64_BLOCK_SIZE; i++) + munit_assert_uchar(ctx.block[i], ==, 0); + return MUNIT_OK; +} + +TEST_RESULT should_encode_base64_buffer(TEST_PARAMS, TEST_DATA) +{ + UNUSED(test_params); + UNUSED(test_data); + + t_base64_ctx ctx; + + ft_base64_init(&ctx); + + ft_base64_fill_buffer(&ctx, (t_byte1 *)"Man", 3); + ft_base64_encode_buffer(&ctx, 3); + munit_assert_string_equal((char *)ctx.chars, "TWFu"); + + ft_base64_fill_buffer(&ctx, (t_byte1 *)"Ma", 2); + ft_base64_encode_buffer(&ctx, 2); + munit_assert_string_equal((char *)ctx.chars, "TWE="); + + ft_base64_fill_buffer(&ctx, (t_byte1 *)"M", 1); + ft_base64_encode_buffer(&ctx, 1); + munit_assert_string_equal((char *)ctx.chars, "TQ=="); return MUNIT_OK; } \ No newline at end of file diff --git a/t/tests.c b/t/tests.c index d896c553..2dc6cb0d 100644 --- a/t/tests.c +++ b/t/tests.c @@ -42,6 +42,9 @@ MunitTest g_sha_tests[] = { MunitTest g_base64_tests[] = { IT("/init_ctx", should_init_base64_ctx, NULL, NULL, 0, NULL), + IT("/fills_buffer", should_fill_base64_buffer, NULL, NULL, 0, NULL), + IT("/cleans_buffer", should_clean_base64_buffer, NULL, NULL, 0, NULL), + IT("/encodes_buffer", should_encode_base64_buffer, NULL, NULL, 0, NULL), END_IT }; diff --git a/watch.sh b/watch.sh new file mode 100755 index 00000000..7468039e --- /dev/null +++ b/watch.sh @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +while true; do + find src t inc Makefile | entr -cd make check -j8 +done