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