1 /** 2 Helper functions. 3 4 `hmac_sha1` and `toRFC822DateTime` functions will become obsolete in future versions of Photos. 5 6 Copyright: © 2015 sigod 7 License: Subject to the terms of the MIT license, as written in the included LICENSE file. 8 Authors: sigod 9 */ 10 module s3.internal.helpers; 11 12 ubyte[20] hmac_sha1(const(ubyte)[] key, const(ubyte)[] message) 13 { 14 import std.digest.sha : sha1Of; 15 16 enum block_size = 64; 17 18 if (key.length > block_size) 19 key = sha1Of(key); 20 if (key.length < block_size) 21 key.length = block_size; 22 23 ubyte[] o_key_pad = key.dup; 24 ubyte[] i_key_pad = key.dup; 25 26 o_key_pad[] ^= 0x5c; 27 i_key_pad[] ^= 0x36; 28 29 return sha1Of(o_key_pad ~ sha1Of(i_key_pad ~ message)); 30 } 31 32 unittest { 33 import std.digest.digest : toHexString; 34 35 auto value = hmac_sha1(cast(ubyte[])"", cast(ubyte[])""); 36 assert(value.toHexString == "FBDB1D1B18AA6C08324B7D64B71FB76370690E1D"); 37 38 value = hmac_sha1(cast(ubyte[])"key", cast(ubyte[])"The quick brown fox jumps over the lazy dog"); 39 assert(value.toHexString == "DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9"); 40 } 41 42 43 private import std.datetime : SysTime; 44 45 // example: Tue, 27 Mar 2007 21:06:08 +0000 46 47 string toRFC822DateTime(in SysTime time) @safe 48 { 49 import std.format : format; 50 try 51 { 52 auto time_ = time.toUTC(); 53 54 assert(time_.year >= 1900); 55 56 return format("%s, %02d %s %04d %02d:%02d:%02d +0000", 57 dayToString(time_.dayOfWeek), time_.day, monthToString(time_.month), time_.year, 58 time_.hour, time_.minute, time_.second 59 ); 60 } 61 catch(Exception e) 62 assert(0, "format() threw."); 63 } 64 65 private: 66 67 // private members of std.datetime: 68 69 import std.datetime; 70 71 immutable string[12] _monthNames = ["Jan", 72 "Feb", 73 "Mar", 74 "Apr", 75 "May", 76 "Jun", 77 "Jul", 78 "Aug", 79 "Sep", 80 "Oct", 81 "Nov", 82 "Dec"]; 83 84 string monthToString(Month month) @safe pure 85 { 86 import std.format : format; 87 assert(month >= Month.jan && month <= Month.dec, format("Invalid month: %s", month)); 88 return _monthNames[month - Month.jan]; 89 } 90 91 unittest 92 { 93 assert(monthToString(Month.jan) == "Jan"); 94 assert(monthToString(Month.feb) == "Feb"); 95 assert(monthToString(Month.mar) == "Mar"); 96 assert(monthToString(Month.apr) == "Apr"); 97 assert(monthToString(Month.may) == "May"); 98 assert(monthToString(Month.jun) == "Jun"); 99 assert(monthToString(Month.jul) == "Jul"); 100 assert(monthToString(Month.aug) == "Aug"); 101 assert(monthToString(Month.sep) == "Sep"); 102 assert(monthToString(Month.oct) == "Oct"); 103 assert(monthToString(Month.nov) == "Nov"); 104 assert(monthToString(Month.dec) == "Dec"); 105 } 106 107 // custom 108 109 immutable string[7] daysOfWeekNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; 110 111 string dayToString(DayOfWeek day) @safe pure 112 { 113 return daysOfWeekNames[day - DayOfWeek.sun]; 114 } 115 116 unittest 117 { 118 assert(dayToString(DayOfWeek.sun) == "Sun"); 119 assert(dayToString(DayOfWeek.mon) == "Mon"); 120 assert(dayToString(DayOfWeek.tue) == "Tue"); 121 assert(dayToString(DayOfWeek.wed) == "Wed"); 122 assert(dayToString(DayOfWeek.thu) == "Thu"); 123 assert(dayToString(DayOfWeek.fri) == "Fri"); 124 assert(dayToString(DayOfWeek.sat) == "Sat"); 125 }