This commit is contained in:
klein panic
2025-02-01 16:14:45 -05:00
commit 3aff0baacf
82 changed files with 1694 additions and 0 deletions

21
Base64_Encoding/README.md Normal file
View 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.

View 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

Binary file not shown.

View 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

Binary file not shown.

BIN
Base64_Encoding/obj/main.o Normal file

Binary file not shown.

View 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;
}

View 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;
}