This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

at master 5.9 kB View raw
1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4#include <time.h> 5#include <stdbool.h> 6 7#define BUFFER_SIZE 4096 8#define MAX_NAMES 128 9 10#define BASE64_CENCODE_H 11 12typedef enum 13{ 14 step_A, step_B, step_C 15} base64_encodestep; 16 17typedef struct 18{ 19 base64_encodestep step; 20 char result; 21 int stepcount; 22} base64_encodestate; 23 24 25/* 26cencoder.c - c source to a base64 encoding algorithm implementation 27 28This is part of the libb64 project, and has been placed in the public domain. 29For details, see http://sourceforge.net/projects/libb64 30*/ 31 32 33const int CHARS_PER_LINE = 72; 34 35void base64_init_encodestate(base64_encodestate* state_in) 36{ 37 state_in->step = step_A; 38 state_in->result = 0; 39 state_in->stepcount = 0; 40} 41 42char base64_encode_value(char value_in) 43{ 44 static const char* encoding = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 45 if (value_in > 63) return '='; 46 return encoding[(int)value_in]; 47} 48 49int base64_encode_block(const char* plaintext_in, int length_in, char* code_out, base64_encodestate* state_in) 50{ 51 const char* plainchar = plaintext_in; 52 const char* const plaintextend = plaintext_in + length_in; 53 char* codechar = code_out; 54 char result; 55 char fragment; 56 57 result = state_in->result; 58 59 switch (state_in->step) 60 { 61 while (1) 62 { 63 case step_A: 64 if (plainchar == plaintextend) 65 { 66 state_in->result = result; 67 state_in->step = step_A; 68 return codechar - code_out; 69 } 70 fragment = *plainchar++; 71 result = (fragment & 0x0fc) >> 2; 72 *codechar++ = base64_encode_value(result); 73 result = (fragment & 0x003) << 4; 74 case step_B: 75 if (plainchar == plaintextend) 76 { 77 state_in->result = result; 78 state_in->step = step_B; 79 return codechar - code_out; 80 } 81 fragment = *plainchar++; 82 result |= (fragment & 0x0f0) >> 4; 83 *codechar++ = base64_encode_value(result); 84 result = (fragment & 0x00f) << 2; 85 case step_C: 86 if (plainchar == plaintextend) 87 { 88 state_in->result = result; 89 state_in->step = step_C; 90 return codechar - code_out; 91 } 92 fragment = *plainchar++; 93 result |= (fragment & 0x0c0) >> 6; 94 *codechar++ = base64_encode_value(result); 95 result = (fragment & 0x03f) >> 0; 96 *codechar++ = base64_encode_value(result); 97 98 ++(state_in->stepcount); 99 if (state_in->stepcount == CHARS_PER_LINE/4) 100 { 101 *codechar++ = '\n'; 102 state_in->stepcount = 0; 103 } 104 } 105 } 106 /* control should not reach here */ 107 return codechar - code_out; 108} 109 110int base64_encode_blockend(char* code_out, base64_encodestate* state_in) 111{ 112 char* codechar = code_out; 113 114 switch (state_in->step) 115 { 116 case step_B: 117 *codechar++ = base64_encode_value(state_in->result); 118 *codechar++ = '='; 119 *codechar++ = '='; 120 break; 121 case step_C: 122 *codechar++ = base64_encode_value(state_in->result); 123 *codechar++ = '='; 124 break; 125 case step_A: 126 break; 127 } 128 *codechar++ = '\n'; 129 130 return codechar - code_out; 131} 132 133char* encode(const char* input) 134{ 135 /* set up a destination buffer large enough to hold the encoded data */ 136 char* output = (char*)malloc(BUFFER_SIZE); 137 /* keep track of our encoded position */ 138 char* c = output; 139 /* store the number of bytes encoded by a single call */ 140 int cnt = 0; 141 /* we need an encoder state */ 142 base64_encodestate s; 143 144 /*---------- START ENCODING ----------*/ 145 /* initialise the encoder state */ 146 base64_init_encodestate(&s); 147 /* gather data from the input and send it to the output */ 148 cnt = base64_encode_block(input, strlen(input), c, &s); 149 c += cnt; 150 /* since we have encoded the entire input string, we know that 151 there is no more input data; finalise the encoding */ 152 cnt = base64_encode_blockend(c, &s); 153 c += cnt; 154 /*---------- STOP ENCODING ----------*/ 155 156 /* we want to print the encoded data, so null-terminate it: */ 157 *c = 0; 158 159 return output; 160} 161 162void shuffle(int *array, int size, unsigned int seed) { 163 srand(seed); 164 for (int i = size - 1; i > 0; i--) { 165 int j = rand() % (i + 1); 166 int temp = array[i]; 167 array[i] = array[j]; 168 array[j] = temp; 169 } 170} 171 172int main(int argc, char *argv[]) { 173 char buffer[BUFFER_SIZE]; 174 char *names[MAX_NAMES]; 175 int indices[MAX_NAMES]; 176 int name_count = 0; 177 unsigned int seed; 178 bool seed_provided = false; 179 bool encode_partner = true; 180 181 for (int i = 1; i < argc; i++) { 182 if (strcmp(argv[i], "-s") == 0 && i + 1 < argc) { 183 seed = (unsigned int)strtoul(argv[i + 1], NULL, 10); 184 seed_provided = true; 185 } 186 if (strcmp(argv[i], "-d") == 0) { 187 encode_partner = false; 188 } 189 } 190 191 if (!seed_provided) { 192 seed = (unsigned int)time(NULL); 193 } 194 195 printf("Seed: %u\n", seed); 196 197 if (fgets(buffer, sizeof(buffer), stdin) == NULL) { 198 perror("Error reading input"); 199 return 1; 200 } 201 202 size_t len = strlen(buffer); 203 if (len > 0 && buffer[len - 1] == '\n') { 204 buffer[len - 1] = '\0'; 205 } 206 207 char *token = strtok(buffer, " "); 208 while (token != NULL) { 209 if (name_count >= MAX_NAMES) { 210 fprintf(stderr, "Too many names (max %d)\n", MAX_NAMES); 211 return 1; 212 } 213 names[name_count] = strdup(token); 214 indices[name_count] = name_count; 215 name_count++; 216 token = strtok(NULL, " "); 217 } 218 219 if (name_count < 2) { 220 fprintf(stderr, "Need at least two names for Secret Santa\n"); 221 return 1; 222 } 223 224 shuffle(indices, name_count, seed); 225 226 int offset = seed; 227 if (offset % name_count == 0) { 228 offset = 1; 229 } 230 for (int i = 0; i < name_count; i++) { 231 int giver = indices[i]; 232 int receiver = indices[(i + offset) % name_count]; 233 if (encode_partner) { 234 printf("%s: %s\n", names[giver], encode(names[receiver])); 235 } else { 236 printf("%s: %s\n", names[giver], names[receiver]); 237 } 238 } 239 240 for (int i = 0; i < name_count; i++) { 241 free(names[i]); 242 } 243 244 return 0; 245}