Complete base64 project
This commit is contained in:
		
							
								
								
									
										142
									
								
								base64/base64.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										142
									
								
								base64/base64.odin
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,142 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "core:math"
 | 
				
			||||||
 | 
					import "core:strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@(private="file")
 | 
				
			||||||
 | 
					alphabet := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					encode :: proc(s: string) -> string {
 | 
				
			||||||
 | 
					  if len(s) == 0 do return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  n_out := calc_encode_length(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bytes := make([]u8, n_out);
 | 
				
			||||||
 | 
					  defer delete(bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  buf : [3]u8 = {};
 | 
				
			||||||
 | 
					  count : u8 = 0;
 | 
				
			||||||
 | 
					  iout : u64 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i in 0..<len(s) {
 | 
				
			||||||
 | 
					    buf[count] = s[i];
 | 
				
			||||||
 | 
					    count += 1;
 | 
				
			||||||
 | 
					    if count == 3 {
 | 
				
			||||||
 | 
					      bytes[iout] = char_at(buf[0] >> 2);
 | 
				
			||||||
 | 
					      bytes[iout + 1] = char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4));
 | 
				
			||||||
 | 
					      bytes[iout + 2] = char_at(((buf[1] & 0x0f) << 2) + (buf[2] >> 6));
 | 
				
			||||||
 | 
					      bytes[iout + 3] = char_at(buf[2] & 0x3f);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      iout += 4;
 | 
				
			||||||
 | 
					      count = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if count == 1 {
 | 
				
			||||||
 | 
					    bytes[iout] = char_at(buf[0] >> 2);
 | 
				
			||||||
 | 
					    bytes[iout + 1] = char_at((buf[0] & 0x03) << 4);
 | 
				
			||||||
 | 
					    bytes[iout + 2] = '=';
 | 
				
			||||||
 | 
					    bytes[iout + 3] = '=';
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if count == 2 {
 | 
				
			||||||
 | 
					    bytes[iout] = char_at(buf[0] >> 2);
 | 
				
			||||||
 | 
					    bytes[iout + 1] = char_at(((buf[0] & 0x03) << 4) + (buf[1] >> 4));
 | 
				
			||||||
 | 
					    bytes[iout + 2] = char_at((buf[1] & 0x0f) << 2);
 | 
				
			||||||
 | 
					    bytes[iout + 3] = '=';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    iout += 4;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  output, err := strings.clone_from_bytes(bytes[:]);
 | 
				
			||||||
 | 
					  if err != nil {
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					decode :: proc(s: string) -> string {
 | 
				
			||||||
 | 
					  if len(s) == 0 do return "";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  n_out := calc_decode_length(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  bytes := make([]u8, n_out);
 | 
				
			||||||
 | 
					  defer delete(bytes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  buf : [4]u8 = {};
 | 
				
			||||||
 | 
					  count : u8 = 0;
 | 
				
			||||||
 | 
					  iout : u64 = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  for i in 0..<len(s) {
 | 
				
			||||||
 | 
					    buf[count] = char_index(s[i]);
 | 
				
			||||||
 | 
					    count += 1;
 | 
				
			||||||
 | 
					    if count == 4 {
 | 
				
			||||||
 | 
					      bytes[iout] = (buf[0] << 2) + (buf[1] >> 4);
 | 
				
			||||||
 | 
					      if buf[2] != 64 {
 | 
				
			||||||
 | 
					        bytes[iout + 1] = (buf[1] << 4) + (buf[2] >> 2);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if buf[3] != 64 {
 | 
				
			||||||
 | 
					        bytes[iout + 2] = (buf[2] << 6) + buf[3];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      iout += 3;
 | 
				
			||||||
 | 
					      count = 0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  output, err := strings.clone_from_bytes(bytes[:]);
 | 
				
			||||||
 | 
					  if err != nil {
 | 
				
			||||||
 | 
					    return "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return output;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@(private="file")
 | 
				
			||||||
 | 
					char_at :: proc(index: u8) -> u8 {
 | 
				
			||||||
 | 
					  return alphabet[index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@(private="file")
 | 
				
			||||||
 | 
					char_index :: proc(char: u8) -> u8 {
 | 
				
			||||||
 | 
					  if char == '=' {
 | 
				
			||||||
 | 
					    return 64;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  index : u8 = 0;
 | 
				
			||||||
 | 
					  for c in alphabet {
 | 
				
			||||||
 | 
					    if c == rune(char) do break;
 | 
				
			||||||
 | 
					    index += 1;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return index;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@(private="file")
 | 
				
			||||||
 | 
					calc_encode_length :: proc(s: string) -> u64 {
 | 
				
			||||||
 | 
					  if len(s) < 3 {
 | 
				
			||||||
 | 
					    return 4;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  groups := u64(math.ceil_f32(f32(len(s)) / 3.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return groups * 4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@(private="file")
 | 
				
			||||||
 | 
					calc_decode_length :: proc(s: string) -> u64 {
 | 
				
			||||||
 | 
					  if len(s) < 4 {
 | 
				
			||||||
 | 
					    return 3;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  n_groups := u64(math.floor_f32(f32(len(s)) / 4.0));
 | 
				
			||||||
 | 
					  groups := n_groups * 3;
 | 
				
			||||||
 | 
					  #reverse for char in s {
 | 
				
			||||||
 | 
					    if char == '=' {
 | 
				
			||||||
 | 
					      groups -= 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return groups;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								base64/main.odin
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								base64/main.odin
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "core:fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main :: proc() {
 | 
				
			||||||
 | 
					  text :: "Testing some more stuff";
 | 
				
			||||||
 | 
					  etext :: "VGVzdGluZyBzb21lIG1vcmUgc3R1ZmY=";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  encoded_text := encode(text);
 | 
				
			||||||
 | 
					  defer delete(encoded_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  decoded_text := decode(etext);
 | 
				
			||||||
 | 
					  defer delete(decoded_text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fmt.println("Encoded text:", encoded_text);
 | 
				
			||||||
 | 
					  fmt.println("Decoded text:", decoded_text);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user