testing
This commit is contained in:
21
Base64_Encoding/README.md
Normal file
21
Base64_Encoding/README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Base64 Encoder
|
||||
|
||||
## Description
|
||||
This project implements a Base64 encoder and decoder for educational purposes. Base64 encoding converts binary data to text, using a set of 64 printable characters.
|
||||
|
||||
## Directory Structure
|
||||
- `include/`: Contains the header files.
|
||||
- `src/`: Contains the source code files (`main.c` and `base64_encoder.c`).
|
||||
- `obj/`: Contains the compiled object files.
|
||||
- `build/`: Contains the Makefile and the compiled binary.
|
||||
|
||||
## How to Build
|
||||
1. Navigate to the `build` directory.
|
||||
2. Run `make` to compile the project.
|
||||
|
||||
## How to Run
|
||||
1. After building, you will find an executable named `base64_encoder` in the `build` directory.
|
||||
2. Run it using `./base64_encoder`.
|
||||
|
||||
## How to Clean
|
||||
- Run `make clean` in the `build` directory to remove all compiled files.
|
||||
28
Base64_Encoding/build/Makefile
Normal file
28
Base64_Encoding/build/Makefile
Normal file
@@ -0,0 +1,28 @@
|
||||
# Variables
|
||||
CC = gcc
|
||||
CFLAGS = -I../include -Wall -Wextra
|
||||
OBJDIR = ../obj
|
||||
SRCDIR = ../src
|
||||
BINDIR = ../build
|
||||
|
||||
# Source files
|
||||
SOURCES = $(SRCDIR)/main.c $(SRCDIR)/base64_encoder.c
|
||||
OBJECTS = $(OBJDIR)/main.o $(OBJDIR)/base64_encoder.o
|
||||
|
||||
# Build target
|
||||
TARGET = base64_encoder
|
||||
|
||||
# Rules
|
||||
all: $(BINDIR)/$(TARGET)
|
||||
|
||||
$(BINDIR)/$(TARGET): $(OBJECTS)
|
||||
$(CC) $(OBJECTS) -o $(BINDIR)/$(TARGET)
|
||||
|
||||
$(OBJDIR)/%.o: $(SRCDIR)/%.c
|
||||
$(CC) $(CFLAGS) -c $< -o $@
|
||||
|
||||
clean:
|
||||
rm -f $(OBJDIR)/*.o $(BINDIR)/$(TARGET)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
BIN
Base64_Encoding/build/base64_encoder
Executable file
BIN
Base64_Encoding/build/base64_encoder
Executable file
Binary file not shown.
9
Base64_Encoding/include/base64_encoder.h
Normal file
9
Base64_Encoding/include/base64_encoder.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef BASE64_ENCODER_H
|
||||
#define BASE64_ENCODER_H
|
||||
|
||||
#include <stddef.h> // Include this to define size_t
|
||||
|
||||
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length);
|
||||
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length);
|
||||
|
||||
#endif // BASE64_ENCODER_H
|
||||
BIN
Base64_Encoding/obj/base64_encoder.o
Normal file
BIN
Base64_Encoding/obj/base64_encoder.o
Normal file
Binary file not shown.
BIN
Base64_Encoding/obj/main.o
Normal file
BIN
Base64_Encoding/obj/main.o
Normal file
Binary file not shown.
96
Base64_Encoding/src/base64_encoder.c
Normal file
96
Base64_Encoding/src/base64_encoder.c
Normal file
@@ -0,0 +1,96 @@
|
||||
#include "base64_encoder.h"
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static const char base64_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
"0123456789+/";
|
||||
|
||||
static int base64_char_value(char c) {
|
||||
if (c >= 'A' && c <= 'Z') return c - 'A';
|
||||
if (c >= 'a' && c <= 'z') return c - 'a' + 26;
|
||||
if (c >= '0' && c <= '9') return c - '0' + 52;
|
||||
if (c == '+') return 62;
|
||||
if (c == '/') return 63;
|
||||
return -1; // Should never happen for valid Base64 strings
|
||||
}
|
||||
|
||||
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
|
||||
*output_length = 4 * ((input_length + 2) / 3);
|
||||
char *encoded_data = (char *)malloc(*output_length + 1);
|
||||
if (encoded_data == NULL) return NULL;
|
||||
|
||||
for (size_t i = 0, j = 0; i < input_length;) {
|
||||
uint32_t octet_a = i < input_length ? (unsigned char)data[i++] : 0;
|
||||
uint32_t octet_b = i < input_length ? (unsigned char)data[i++] : 0;
|
||||
uint32_t octet_c = i < input_length ? (unsigned char)data[i++] : 0;
|
||||
|
||||
uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c;
|
||||
|
||||
encoded_data[j++] = base64_chars[(triple >> 18) & 0x3F];
|
||||
encoded_data[j++] = base64_chars[(triple >> 12) & 0x3F];
|
||||
encoded_data[j++] = base64_chars[(triple >> 6) & 0x3F];
|
||||
encoded_data[j++] = base64_chars[triple & 0x3F];
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < ((3 - (input_length % 3)) % 3); i++) {
|
||||
encoded_data[*output_length - 1 - i] = '=';
|
||||
}
|
||||
|
||||
encoded_data[*output_length] = '\0';
|
||||
return encoded_data;
|
||||
}
|
||||
|
||||
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
|
||||
if (input_length % 4 != 0) {
|
||||
printf("Error: Input length is not a multiple of 4.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Calculate output length, ignoring padding characters '='
|
||||
*output_length = (input_length / 4) * 3;
|
||||
if (data[input_length - 1] == '=') (*output_length)--;
|
||||
if (data[input_length - 2] == '=') (*output_length)--;
|
||||
|
||||
unsigned char *decoded_data = (unsigned char *)malloc(*output_length);
|
||||
if (decoded_data == NULL) {
|
||||
printf("Error: Memory allocation failed.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t i = 0, j = 0;
|
||||
while (i < input_length) {
|
||||
if (data[i] == '=') {
|
||||
break; // Stop if we hit padding
|
||||
}
|
||||
|
||||
// Read four Base64 characters and map them to their 6-bit values
|
||||
int sextet_a = base64_char_value(data[i++]);
|
||||
int sextet_b = base64_char_value(data[i++]);
|
||||
int sextet_c = (i < input_length && data[i] != '=') ? base64_char_value(data[i++]) : 0;
|
||||
int sextet_d = (i < input_length && data[i] != '=') ? base64_char_value(data[i++]) : 0;
|
||||
|
||||
if (sextet_a == -1 || sextet_b == -1 || sextet_c == -1 || sextet_d == -1) {
|
||||
printf("Error: Invalid Base64 character detected.\n");
|
||||
free(decoded_data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Combine the four 6-bit sextets into three bytes
|
||||
uint32_t triple = (sextet_a << 18) | (sextet_b << 12) | (sextet_c << 6) | sextet_d;
|
||||
|
||||
if (j < *output_length) decoded_data[j++] = (triple >> 16) & 0xFF;
|
||||
if (j < *output_length) decoded_data[j++] = (triple >> 8) & 0xFF;
|
||||
if (j < *output_length) decoded_data[j++] = triple & 0xFF;
|
||||
|
||||
// Break once we have decoded the expected number of bytes
|
||||
if (j >= *output_length) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return decoded_data;
|
||||
}
|
||||
|
||||
39
Base64_Encoding/src/main.c
Normal file
39
Base64_Encoding/src/main.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "base64_encoder.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h> // Include this for memory management functions like free
|
||||
|
||||
int main() {
|
||||
char message[256];
|
||||
size_t output_length;
|
||||
|
||||
printf("Enter a message to encode: ");
|
||||
fgets(message, sizeof(message), stdin);
|
||||
message[strcspn(message, "\n")] = '\0'; // Remove newline character
|
||||
|
||||
// Encode the message
|
||||
char *encoded = base64_encode((unsigned char *)message, strlen(message), &output_length);
|
||||
if (encoded == NULL) {
|
||||
printf("Failed to encode the message.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Encoded message: %s\n", encoded);
|
||||
|
||||
// Decode the message
|
||||
size_t decoded_length;
|
||||
unsigned char *decoded = base64_decode(encoded, output_length, &decoded_length);
|
||||
if (decoded == NULL) {
|
||||
printf("Failed to decode the message.\n");
|
||||
free(encoded);
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("Decoded message: %.*s\n", (int)decoded_length, decoded);
|
||||
|
||||
// Clean up
|
||||
free(encoded);
|
||||
free(decoded);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user