Skip to content

Instantly share code, notes, and snippets.

@twobob
Created July 31, 2023 13:31
Show Gist options
  • Save twobob/1834df2e97081e74cbb0762f0a802866 to your computer and use it in GitHub Desktop.
Save twobob/1834df2e97081e74cbb0762f0a802866 to your computer and use it in GitHub Desktop.
base64_urlsafe kinda roughly. for the recoverable filenames.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <direct.h>
#include <time.h>
static inline void process_triplet(const char *input, size_t i, uint32_t *triplet) {
*triplet = (input[i] << 16) | (i + 1 < strlen(input) ? input[i + 1] << 8 : 0) | (i + 2 < strlen(input) ? input[i + 2] : 0);
}
static inline void process_quartet(const char *input, size_t i, uint32_t *quartet, int *k, const char *base64_urlsafe_table) {
*quartet = 0;
for (*k = 0; *k < 4; (*k)++) {
char c = input[i + *k];
if (c == '=') break;
char* pos = strchr(base64_urlsafe_table, c);
if (!pos) { *quartet = UINT32_MAX; break; }
*quartet = (*quartet << 6) | (pos - base64_urlsafe_table);
}
*quartet <<= 6 * (4 - *k);
}
static char* encode_triplets(const char *input, size_t len) {
static const char base64_urlsafe_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
size_t output_len = 4 * ((len + 2) / 3);
char *output = (char*)malloc(output_len + 1);
if (!output) return NULL;
int i, j;
for (i = 0, j = 0; i < len; i += 3) {
uint32_t triplet;
process_triplet(input, i, &triplet);
output[j++] = base64_urlsafe_table[(triplet >> 18) & 0x3F];
output[j++] = base64_urlsafe_table[(triplet >> 12) & 0x3F];
output[j++] = i + 1 < len ? base64_urlsafe_table[(triplet >> 6) & 0x3F] : '=';
output[j++] = i + 2 < len ? base64_urlsafe_table[triplet & 0x3F] : '=';
}
output[output_len] = '\0';
return output;
}
static char* decode_quartets(const char *input, size_t len) {
static const char base64_urlsafe_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=";
if (len % 4 != 0) return NULL;
size_t output_len = len / 4 * 3;
if (input[len - 1] == '=') output_len--;
if (input[len - 2] == '=') output_len--;
char* output = (char*)malloc(output_len + 1);
if (!output) return NULL;
int i, j;
for (i = 0, j = 0; i < len; i += 4) {
uint32_t quartet;
int k;
process_quartet(input, i, &quartet, &k, base64_urlsafe_table);
if (quartet == UINT32_MAX) { free(output); output = NULL; break; }
if (k > 1) output[j++] = (quartet >> 16) & 0xFF;
if (k > 2) output[j++] = (quartet >> 8) & 0xFF;
if (k > 3) output[j++] = quartet & 0xFF;
}
if (output) output[output_len] = '\0';
return output;
}
// ----------------------------------------------------------------------------
// borrowed utilities
long time_in_ms() {
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return time.tv_sec * 1000 + time.tv_nsec / 1000000;
}
int main() {
// for saving files
time_t t = time(NULL);
struct tm *tm_info = localtime(&t);
char timestamp[26];
strftime(timestamp, 26, "%Y%m%d%H%M%S", tm_info);
char dirname[] = "inbox";
// Check if directory exists
if (_access(dirname, 0) == -1) {
printf("Directory %s does not exist. Attempting to create it.\n", dirname);
// If directory doesn't exist, create it
if (_mkdir(dirname) == -1) {
printf("Unable to create directory %s!\n", dirname);
return 1;
}
}
char filename[150];
char *prompt = "This could be a prompt";
snprintf(filename, 150, "inbox/%s_?_%s.txt", timestamp, prompt);
FILE *output_file = NULL; // Declare output_file outside the if statement
//const char* original_string = filename;
char* encoded_string = encode_triplets(filename, strlen(filename));
output_file = fopen(encoded_string, "w");
if (!output_file) {
printf("Unable to open the inbox file %s!\n", encoded_string);
return 1;
}
char* decoded_string = decode_quartets(encoded_string, strlen(encoded_string));
printf("Original: %s\n", filename);
printf("Encoded: %s\n", encoded_string);
printf("Decoded: %s\n", decoded_string);
free(encoded_string);
free(decoded_string);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment