1 module itsdangerous.encoding; 2 3 import std.base64: Base64URLNoPadding, Base64Exception; 4 import std.conv; 5 import std.array; 6 import std.encoding; 7 import std.string: representation; 8 9 import itsdangerous.exc; 10 11 __gshared immutable string BASE64_ALPHABET = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_="; 12 13 string base64Encode(T = string)(T s){ 14 static if (is(T == string)){ 15 return Base64URLNoPadding.encode(s.representation); 16 } else 17 static if (is(T == ubyte[])) { 18 return Base64URLNoPadding.encode(s); 19 } 20 21 } 22 23 string base64Decode(string s){ 24 try{ 25 return cast(string)Base64URLNoPadding.decode(s); 26 } catch (Base64Exception ex) { 27 throw new BadData("Invalid base64-encoded data: " ~ ex.msg); 28 } 29 } 30 31 ubyte[] intToBytes(int n){ 32 ubyte[4] bytes; 33 34 bytes[0] = (n >> 24) & 0xFF; 35 bytes[1] = (n >> 16) & 0xFF; 36 bytes[2] = (n >> 8) & 0xFF; 37 bytes[3] = n & 0xFF; 38 39 return bytes.dup; 40 } 41 42 int bytesToInt(ubyte[] bytes){ 43 return ((bytes[0] & 0xFF) << 24) + ((bytes[1] & 0xFF ) << 16) + ((bytes[2] & 0xFF ) << 8) + (bytes[3] & 0xFF); 44 } 45 46 auto rsplit(string str, char sep){ // emulating behaviour of python rsplit 47 auto arr = str.split(sep); 48 if(arr.length == 2) 49 return arr; 50 else if (arr.length == 3){ 51 auto last = arr[$-1]; 52 arr.popBack(); 53 return [arr[0] ~ sep ~ arr[1], last]; 54 } else { 55 throw new Exception("Unexpected signature: more than 3 elements!"); 56 } 57 } 58 59 unittest { 60 assert(intToBytes(1577992918) == [94, 14, 66, 214]); 61 assert(bytesToInt(intToBytes(1577992918)) == 1577992918); 62 }