[Add] Start of base64 encode/decode routines. Not quite working yet.
This commit is contained in:
		
							parent
							
								
									e77ac4a022
								
							
						
					
					
						commit
						8b12c22369
					
				
							
								
								
									
										105
									
								
								src/base64.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								src/base64.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,105 @@
 | 
				
			|||||||
 | 
					#include <malloc.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode table.
 | 
				
			||||||
 | 
					static const char cb64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstu \
 | 
				
			||||||
 | 
					                            vwxyz0123456789+/";
 | 
				
			||||||
 | 
					// Decode table.
 | 
				
			||||||
 | 
					static const char cd64[] = "|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW \
 | 
				
			||||||
 | 
					                            $$$$$$XYZ[\\]^_'abcdefghijklmnopq";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Encode src of sz length storing the new length in len.
 | 
				
			||||||
 | 
					char* base64_encode(int* len, char* src, size_t sz) {
 | 
				
			||||||
 | 
					  char* r;
 | 
				
			||||||
 | 
					  size_t i, c;
 | 
				
			||||||
 | 
					  uint32_t n;
 | 
				
			||||||
 | 
					  uint8_t ch[4], pad;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create r.
 | 
				
			||||||
 | 
					  c = sz * 4 / 3 + sz % 3;
 | 
				
			||||||
 | 
					  c += c / 76;
 | 
				
			||||||
 | 
					  (*len) = c;
 | 
				
			||||||
 | 
					  r = malloc((*len) * sizeof(char));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Setup padding.
 | 
				
			||||||
 | 
					  pad = sz % 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Time to do the bulk of the work.
 | 
				
			||||||
 | 
					  i = 0;
 | 
				
			||||||
 | 
					  for(c = 0; c < sz; c += 3) {
 | 
				
			||||||
 | 
					    // Specification wants newline after every 76 characters.
 | 
				
			||||||
 | 
					    if((c > 0) && ((c / 3 * 4) % 76 == 0))
 | 
				
			||||||
 | 
					      r[i++] = '\n';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // n is 24 bits.
 | 
				
			||||||
 | 
					    n = (src[c] << 16) +
 | 
				
			||||||
 | 
					      (c+1<sz) ? (src[c+1] << 8) : 0 +  // May be out of range.
 | 
				
			||||||
 | 
					      (c+2<sz) ? src[c+2] : 0;          // May be out of range.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ch[0-3] are 6 bits each.
 | 
				
			||||||
 | 
					    ch[0] = (n >> 18) & 63;
 | 
				
			||||||
 | 
					    ch[1] = (n >> 12) & 63;
 | 
				
			||||||
 | 
					    ch[2] = (n >> 6)  & 63;
 | 
				
			||||||
 | 
					    ch[3] = n         & 63;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    r[i++] = cb64[ch[0]];
 | 
				
			||||||
 | 
					    r[i++] = cb64[ch[1]];
 | 
				
			||||||
 | 
					    r[i++] = cb64[ch[2]];
 | 
				
			||||||
 | 
					    r[i++] = cb64[ch[3]];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  for(c = 0; c < pad; c++)
 | 
				
			||||||
 | 
					    r[i++] = '=';
 | 
				
			||||||
 | 
					  r[i] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline int dec_valid(char inp) {
 | 
				
			||||||
 | 
					  if((inp < 43) || (inp > 122) || cd64[(int)inp-43] == '$')
 | 
				
			||||||
 | 
					    return 0;
 | 
				
			||||||
 | 
					  return 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline char dec_ch(char inp) {
 | 
				
			||||||
 | 
					  return cd64[(int)inp-43] - 61;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* base64_decode(int* len, char* src, size_t sz) {
 | 
				
			||||||
 | 
					  char* r, *dat;
 | 
				
			||||||
 | 
					  size_t c, i, j;
 | 
				
			||||||
 | 
					  uint32_t n;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Allocate r.
 | 
				
			||||||
 | 
					  c = sz * 3 / 4;
 | 
				
			||||||
 | 
					  r = malloc(c * sizeof(char));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a clean version of the text.
 | 
				
			||||||
 | 
					  dat = malloc(sz * sizeof(char));
 | 
				
			||||||
 | 
					  j = 0;
 | 
				
			||||||
 | 
					  for(i = 0; i < sz; i++) {
 | 
				
			||||||
 | 
					    if(src[i] == '=')
 | 
				
			||||||
 | 
					      dat[j++] = '\0';
 | 
				
			||||||
 | 
					    else if(dec_valid(src[i]))
 | 
				
			||||||
 | 
					      dat[j++] = src[i];
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Fill r.
 | 
				
			||||||
 | 
					  i = 0;
 | 
				
			||||||
 | 
					  for(c = 0; c < j; c += 4) {
 | 
				
			||||||
 | 
					    n = dec_ch(dat[c+0]) << 18;
 | 
				
			||||||
 | 
					    n = dec_ch(dat[c+1]) << 12;
 | 
				
			||||||
 | 
					    n = dec_ch(dat[c+2]) << 6;
 | 
				
			||||||
 | 
					    n = dec_ch(dat[c+3]) << 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    r[i++] = (n >> 16)  & 0xFF;
 | 
				
			||||||
 | 
					    r[i++] = (n >> 8)   & 0xFF;
 | 
				
			||||||
 | 
					    r[i++] = (n >> 0)   & 0xFF;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  (*len) = i;
 | 
				
			||||||
 | 
					  return r;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/base64.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/base64.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					char* base64_encode(int* len, char* src, size_t sz);
 | 
				
			||||||
 | 
					char* base64_decode(int* len, char* src, size_t sz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user