Complete base64 project
This commit is contained in:
commit
d03bda416f
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);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user