Recent Entries 10
- pattern minor 112d agoConverting to and from Base64 using OpenSSL APII am trying to get a working and good version of base64 conversions using OpenSSL. My alternatives were an implementation from an answer on SO and Boost (which I didn't chose because I read that is pretty broken). I will need OpenSSL in my project and I thought it would be a good idea to use it for base64 too so I can get use with the API. For start, let's just assume: ``` using ByteBuffer = std::vector; ``` This is the header (`redi` is the main namespace of my project): ``` #ifndef REDI_BASE64_HPP #define REDI_BASE64_HPP #include "../bytebuffer.hpp" namespace redi { namespace util { namespace base64 { ByteBuffer encode(const ByteBuffer& data); ByteBuffer encode(const std::string& str); std::string encodeToString(const std::string& str); ByteBuffer decode(const ByteBuffer& data); ByteBuffer decode(const std::string& str); std::string decodeToString(const ByteBuffer& data); std::string decodeToString(const std::string& str); } // namespace base64 } // namespace util } // namespace redi #endif // REDI_BASE64_HPP ``` and here is the source file: ``` #include #include #include #include #include #include #include "base64.hpp" namespace redi { namespace util { namespace base64 { namespace { void rawBase64Encode(const std::uint8_t* input, std::size_t inputLen, char*& output, std::size_t& outputLen) { BIO* bio; BIO* b64; BUF_MEM* bufferPtr; b64 = BIO_new(BIO_f_base64()); bio = BIO_new(BIO_s_mem()); bio = BIO_push(b64, bio); BIO_set_flags(bio, BIO_FLAGS_BASE64_NO_NL); BIO_write(bio, input, static_cast(inputLen)); BIO_flush(bio); BIO_get_mem_ptr(bio, std::addressof(bufferPtr)); BIO_set_close(bio, BIO_NOCLOSE); output = bufferPtr->data; outputLen = bufferPtr->length; free(bufferPtr); BIO_free_all(bio); } std::size_t calcDecodeLength(const std::uint8_t* input, std::size_t len) { std::size_t padding = 0; if (input[len - 1] == '=') { ++padding; if (input[len - 2] == '=') ++padding; } return len * 3 / 4 -
- pattern minor 112d agoEncode strings as base64I have this function I've written to encode strings of binary data as base64 strings. I'd like to see if there are areas where it could be improved, specifically: - Is the function correct? Are there edge cases I haven't accounted for? (Handling arbitrary UTF-8 correctly is a "nice-to-have" but not a "need-to-have" if it significantly increases complexity, but it should be able to handle arbitrary ASCII, treating control and whitespace characters as normal characters) - Can the performance of the algorithm I used be improved? Am I mistaken that its time and space complexities are both O(n), and can either be improved further? Can this problem be parallelized nicely? - Can it safely accept arbitrary/malicious input? - Am I using the right language features for the best performance? (The strings in this case would be generated at runtime, but it would be interesting if anyone wanted to show how to do it with template magic at compile-time, which is a few steps above my level). - Is it idiomatic, modern code that follows best practices? Am I relying on any nonstandard behavior? (Not necessarily a problem, but good to know). `#include "ToBase64.h" // string, experimental/string_view #include #include using std::length_error; // stdexcept using std::string; // string using std::experimental::string_view; // experimental/string_view using std::uint8_t; // cinttypes string to_base64(const string_view input) { static constexpr auto BASE64{ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" }; const auto len{ input.length() }; string output; if (len > output.max_size() / 4 * 3 - 4) { throw length_error{ "Output too large to fit in std::string" }; } output.reserve(len / 3 * 4 + 4); auto remainder{ 0 }; uint8_t leftover{ 0 }; for (uint8_t c : input) { switch ((remainder %= 3)++) { case 0:
- pattern minor 112d agoBase64 implementation in C#I've written the following unsafe C# method to convert a byte array to Base64 encoding. It works, but it runs at a significantly slower rate than the built-in `Convert.ToBase64String` method. ``` public static unsafe string From(byte[] data) { int div = data.Length / 3; int mod = data.Length % 3; int length = data.Length; int b64Length = div * 4 + (mod == 0 ? 0 : 4); int c = 0; char[] r = new char[b64Length]; fixed (char* tblPointer = base64Table) fixed (char* rPointer = r) fixed (byte* dPointer = data) { for (int i = 0; i > 2]; rPointer[c + 1] = tblPointer[((dPointer[i] & 0x03) > 4)]; rPointer[c + 2] = tblPointer[((dPointer[i + 1] & 0x0f) > 6)]; rPointer[c + 3] = tblPointer[((dPointer[i + 2]) & 0x3f)]; c += 4; } switch (mod) { case 1: rPointer[c] = tblPointer[(dPointer[length - 1] & 0xfc) >> 2]; rPointer[c + 1] = tblPointer[((dPointer[length - 1] & 0x03) > 2]; rPointer[c + 1] = tblPointer[((dPointer[length - 2] & 0x03) > 4)]; rPointer[c + 2] = tblPointer[((dPointer[length - 1] & 0x0f) << 2)]; rPointer[c + 3] = '='; c += 4; break; } } return new string(r); } ``` I looked at the Reference Source for the .NET method and found that my code is very very similar already. Is there something I'm missing or is there some sort of optimization to the built in method I don't know about? The variable `base64Table` in the code is simply a `char[]` with the relevant base64 characters. The results being 31 Ticks for the built in method and 2230 Ticks for my method, measured with the `System.Diagnostics.Stopwatch` class.
- pattern minor 112d agoHex string to Base64The base64 decode algorithm is taken directly from Base64 wiki page. This exercise is meant to help me learn Rust, so any pointers in that general direction are very welcome. :) ``` fn main() { println!("{}", hex_to_base64("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d")); } fn hex_to_base64(hex_string: &str) -> String { println!("Converting {} from hex to base64", hex_string); let alphabet: Vec = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".chars().collect(); // Decode the input string from hex into individual bytes let input_chars: Vec = hex_string.chars().collect(); let mut decoded_bytes: Vec = Vec::new(); for i in 0..hex_string.len() { if i % 2 != 0 { continue } let first_byte = input_chars[i].to_digit(16).unwrap() as u8; let second_byte = input_chars[i + 1].to_digit(16).unwrap() as u8; println!("Decoding 0x{}{} to bytes:", input_chars[i], input_chars[i + 1]); let byte = (first_byte > 2; output.push(alphabet[b as usize]); b = (decoded_bytes[i] & 0x03) > 4; output.push(alphabet[b as usize]); b = (decoded_bytes[i + 1] & 0x0F) > 6; output.push(alphabet[b as usize]); b = decoded_bytes[i + 2] & 0x3F; output.push(alphabet[b as usize]); } else { output.push(alphabet[b as usize]); output.push('='); } } else { output.push(alphabet[b as usize]); output.push_str("=="); } } return output } #[test] fn test_hex_to_base64() { assert!(hex_to_base64("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d") == String::from("SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t")); } ```
- snippet minor 112d agoConvert hex to base64, part 2Original question Reimplemented solution following JS1's answer. Changed bit string hack to bitwise operations to get the corresponding base64 index values. ``` #include #include void get_b64_quads(char *hex, char *b64quads, int pad) { char *dec_2_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; char b1 = hex[0] >> 2; char b2 = ((hex[0] & 0x03) > 4); char b3 = ((hex[1] & 0x0f) > 6); char b4 = hex[2] & 0x3f; b64quads[0] = dec_2_base64[b1]; b64quads[1] = dec_2_base64[b2]; b64quads[2] = pad == 1 && !b3 ? '=' : dec_2_base64[b3]; b64quads[3] = pad && !b4 ? '=' : dec_2_base64[b4]; return; } char* hex_2_base64(char *_hex) { int hexstring_size = strlen(_hex); if (!hexstring_size) return NULL; if (hexstring_size % 2 != 0) return NULL; //remove whitespaces from hex string char *moveto = NULL; char *p = _hex; while (*p) { if (*p == ' ') { if (moveto == NULL) moveto = p; } else { if (moveto) { memmove(moveto, p, strlen(p) + 1); moveto = NULL; } } p++; } //converts hex string to byte array int bytearray_size = hexstring_size / 2; //each pair of hex chars is a byte char *bytearray = malloc(bytearray_size); p = _hex; char *bytearray_p = bytearray; char hexbytebuffer[3] = { 0 }; int temp = hexstring_size; int ibytearray = 0; while (temp > 0) { memcpy(hexbytebuffer, p, 2); bytearray[ibytearray] = strtol(hexbytebuffer, NULL, 16); ibytearray++; p += 2; temp -= 2; } //allocate memory for base64 output (must be freed by whoever calls this function) int b64length = (((hexstring_size + 2) / 3) * 4) + 1; //each 3 hex bytes will become 4 base64 chars char *base64 = malloc(b64length + 1); memset(base64, 0, b64length + 1); //walk through byte array, converting each 3 bytes to 4 base64 characters temp = bytearray_size; char *bytearrayp = bytearray; char bytes[3] = { 0 }; ch
- snippet minor 112d agoMatasano Cryptopals Challenge 1: convert hex to base64Cryptopals challenge 1 Using binary strings to convert from hex to binary felt kinda hacky. I'd like to hear if there are better ways to do that. I used `memcpy()` and pointer to the end of the string instead of `strcat()` to avoid the Shlemiel the Painter problem. EDIT: follow up question ``` #include #include char* hex_2_base64(char *_hex) { char *hex_2_bin[16] = { "0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111" }; char *dec_2_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; //allocating memory for binary string int bin_size = strlen(_hex) * 4; while (bin_size % 6 != 0) //add space for zero padding bin_size += 8; char *bin = malloc(bin_size + 1); memset(bin, 0, bin_size + 1); //these are for strtol, its arguments need the zero terminator char buf[2] = { 0 }; char b64buf[6 + 1] = { 0 }; //converting hex input to binary char *bin_end = bin; for (int i = 0; i < strlen(_hex); i++) { buf[0] = _hex[i]; memcpy(bin_end, hex_2_bin[strtol(buf, NULL, 16)], 4); bin_end += 4; } //pad binary string w/ zeroes while (strlen(bin) < bin_size) strcat(bin, "00000000"); //allocating memory for b64 output int b64size = (strlen(bin) / 6) + 1; char *out = malloc(b64size); memset(out, 0, b64size); //walk through binary string, converting chunks of 6 bytes into base64 chars char *bin_ptr = bin; char *out_end = out; int index_b64; while (*bin_ptr) { strncpy(b64buf, bin_ptr, 6); index_b64 = strtol(b64buf, NULL, 2); if (index_b64 == 0) buf[0] = '='; else buf[0] = dec_2_base64[index_b64]; memcpy(out_end, buf, 1); out_end += 1; bin_ptr += 6; } free(bin); return out; } int main(void) { char *out = NULL; out = hex_2_base64("49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d"); assert(strcmp(out, "SSdtIGtpbG
- pattern minor 112d agoUnix-to-Unix Encoding (Uuencoding)Uuencoding is historically used to encode emails. Instructions for creating a Uuencoder are: - Start with 3 bytes from the source, 24 bits in total. - Split into 4 6-bit groupings, each representing a value in the range 0 to 63: bits (00-05), (06-11), (12-17) and (18-23). - Add 32 to each of the values. With the addition of 32 this means that the possible results can be between 32 (" " space) and 95 ("_" underline). 96 ("`" grave accent) as the "special character" is a logical extension of this range. - Output the ASCII equivalent of these numbers. ``` import platform def dec_to_bin(int): return bin(int).replace('0b', '') def uuencode(string, filename): if platform.system() == 'Windows': mode = '644' elif platform.system() == 'Linux': mode = '744' trail = 'begin ' + mode + ' ' + filename + '\n' string_values = [] char_list = list(string) bytes = '' for char in char_list: string_values.append(ord(char)) for ascii in string_values: bytes += dec_to_bin(ascii) three_byte = [bytes[p:p+24] for p in range(0, len(bytes), 24)] if len(three_byte[-1]) < 24: three_byte[-1] += (24 - len(three_byte[-1])) * '0' four_six_bits = [three_byte[n][m:m+6] for n in range(len(three_byte)) for m in range(0, 24, 6)] four_six_bits = [four_six_bits[k:k+4] for k in range(0, len(four_six_bits), 4)] decimal_list = [] for x in range(len(four_six_bits)): for z in range(4): decimal_list.append(int(four_six_bits[x][z], 2)) for index, decimal in enumerate(decimal_list): decimal_list[index] += 32 encoded_chars = [chr(decimal_list[o]) for o in range(len(decimal_list))] length_char = chr(len(encoded_chars) + 32) trail += length_char for newchar in encoded_chars: trail += newchar trail += '\n' + '`' + '\n' + 'end' + '\n' return trail ```
- pattern minor 112d agoBase64 encoder and decoderI'd like to have some feedback on this small snippet I wrote to implement a base64 encoder and decoder. Specifically, I'm not sure I'm handling padding in the best way possible. ``` import string values = string.ascii_uppercase + string.ascii_lowercase + string.digits + '+/' ALPHABET = dict(zip(range(64), values)) def encode(unpadded_buf): padded_buf = unpadded_buf[:] if len(padded_buf) % 3 != 0: padded_buf += [0] * (3 - len(unpadded_buf) % 3) encoded_padded_buf = [] for i in range(0, len(unpadded_buf), 3): encoded_padded_buf += [ padded_buf[i] >> 2 ] encoded_padded_buf += [ (padded_buf[i] & 3) > 4 ] encoded_padded_buf += [ (padded_buf[i + 1] & 15) > 6 ] encoded_padded_buf += [ padded_buf[i + 2] & 63] asciied = ''.join(map(lambda n: ALPHABET[n], encoded_padded_buf)) if len(padded_buf) - len(unpadded_buf) == 2: return asciied[:-2] + '==' elif len(padded_buf) - len(unpadded_buf) == 1: return asciied[:-1] + '=' return asciied[:] def decode(asciied): _alphabet = dict(map(lambda p: (p[1], p[0]), ALPHABET.items())) encoded_buf = list(map(lambda c: _alphabet.get(c, 0), asciied)) decoded_buf = [] for i in range(0, len(encoded_buf), 4): decoded_buf += [ encoded_buf[i] > 4 ] decoded_buf += [ (encoded_buf[i + 1] & 15) > 2 ] decoded_buf += [ (encoded_buf[i + 2] & 3) << 6 | encoded_buf[i + 3] ] return decoded_buf if __name__ == '__main__': assert bytes(decode(encode(list('foo'.encode())))).decode() == 'foo' ```
- pattern minor 112d agoBarcode (Code 128)I wrote the code below to generate Code 128 barcodes, based on the specs. ``` Public Class UcBarCode 'Inherits UserControl Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click PictureBox1.Image = C128bmp("Teste123") WebBrowser1.DocumentText = String.Format("", C128b64png("Teste123")) End Sub Function C128b64png(ByVal text As String) As String Dim bmp = C128bmp(text), str = New IO.MemoryStream bmp.Save(str, Imaging.ImageFormat.Png) Return System.Convert.ToBase64String(str.ToArray) End Function Function C128bmp(ByVal text As String) As Bitmap text = String.Concat(text.Select(Function(c) IIf(AscW(c) >= 32 AndAlso AscW(c) <= 126, c, "_"c))) Dim bars = C128bars(text), bmp As New Bitmap(bars.Sum, 50), x = 0, clr = Color.White For Each bar In bars For i = 1 To bar 'As many columns as bar width For y = 0 To bmp.Height - 1 bmp.SetPixel(x, y, clr) 'Colors column from top to bottom Next x += 1 'Step to next column Next If clr = Color.White Then clr = Color.Black Else clr = Color.White 'Alternates colors B&W Next Return bmp End Function Function C128bars(ByVal text As String) As Integer() Dim chars = text.ToCharArray, bw, vl As New List(Of Integer) bw.Add(10) 'Leading Quiet Zone If chars.All(Function(c) "0123456789".Contains(c)) Then bw.AddRange(GetBarset(105)) 'Start bars for Code C (digit optimized) vl.Add(105) Dim pairs As New List(Of String) For i = 0 To chars.Count - 1 Step 2 pairs.Add(String.Concat(chars.Skip(i).Take(2))) 'Gro
- pattern minor 112d agoMatasano cryptopals: Conversion to base 64 (with generic types)My main interest is in how I have handled the generics and if it's idiomatic. I want the user to be able to specify what kind of integer type they would like to use for the encoding (u8, u16, u32, u64). I want to keep the hex string -> vector of numbers and vector of numbers -> base 64 string conversions separate. My first worry is around specifying the traits of my generic. I've done so with: ``` ``` Perhaps I should of created my own custom type listing all the required traits explicitly and used that? My second worry is how I interact with raw primitive types: ``` FromPrimitive::from_u64(0).unwrap(); ``` and: ``` ToPrimitive::to_u8(&to_encode).unwrap() ``` It would obviously be nicer to not have this messy conversion in cases where I know it's OK: ``` let a:T = 0;//vs FromPrimitive::from_u64(0).unwrap(); ``` Feedback on these issues is most important to me, but more general comments also welcome! I do wonder if in real life the use of generics here is even useful (violates KISS?). http://cryptopals.com/sets/1/challenges/1/ is the specific challenge this code is for. ``` extern crate num; use self::num::traits::PrimInt; use self::num::{ToPrimitive, FromPrimitive}; use std::mem::size_of; use std::char; pub fn hex_decode(hex:&str) -> Vec{ let num_of_4_bits = (size_of::()*8) / 4; let mut hex_bytes:Vec = Vec::new(); let zero:T = FromPrimitive::from_u64(0).unwrap(); hex_bytes.resize(hex.len()/num_of_4_bits, zero); for (index, character) in hex.chars().enumerate(){ let modulus = index % num_of_4_bits; let shift = 4 * ((num_of_4_bits - 1) - modulus); let decoded_hex:T = FromPrimitive::from_u32(character.to_digit(16).unwrap()).unwrap(); let hex_index = index/num_of_4_bits; hex_bytes[hex_index] = hex_bytes[hex_index] | (decoded_hex (raw_binary: &mut Vec){ while raw_binary.len() % 3 != 0{ raw_binary.push(FromPrimitive::from_u64(0).unwrap()); } } fn handle_carried_bits(carried_over