• R/O
  • HTTP
  • SSH
  • HTTPS

mhash384: Commit

MHash-384 development repository


Commit MetaInfo

Revision586d5497a0c89b790ce24a947abcfbeafde12926 (tree)
Zeit2020-02-17 05:39:30
AutorLoRd_MuldeR <mulder2@gmx....>
CommiterLoRd_MuldeR

Log Message

Added support for Base85 (Ascii85) encoding.

Ändern Zusammenfassung

Diff

--- a/frontend/src/common.h
+++ b/frontend/src/common.h
@@ -71,7 +71,7 @@ typedef struct
7171 {
7272 bool keep_going;
7373 bool short_format;
74- bool base64;
74+ int base_enc;
7575 bool lower_case;
7676 bool benchmark;
7777 }
--- a/frontend/src/main.cpp
+++ b/frontend/src/main.cpp
@@ -97,6 +97,7 @@ static void print_manpage(const CHAR_T *const argv0)
9797 FPUTS(STR(" --short Print the digest in short format (no file names)\n"), stderr);
9898 FPUTS(STR(" --lower-case Print the digest in lower-case letters (default: upper-case)\n"), stderr);
9999 FPUTS(STR(" --base64 Print the digest in Base64 format (default: Hex format)\n"), stderr);
100+ FPUTS(STR(" --base85 Print the digest in Base85 format (default: Hex format)\n"), stderr);
100101 FPUTS(STR(" --help Print help screen and exit\n"), stderr);
101102 FPUTS(STR(" --version Print program version and exit\n"), stderr);
102103 FPUTS(STR(" --self-test Run self-test and exit\n"), stderr);
@@ -106,6 +107,21 @@ static void print_manpage(const CHAR_T *const argv0)
106107 }
107108
108109 /*
110+ * Encode digest string
111+ */
112+static std::string encode_digest(const uint8_t *const digest, const options_t &options)
113+{
114+ if (options.base_enc)
115+ {
116+ return ((options.base_enc > 1U) ? bytes_to_base85(digest, MHASH384_SIZE) : bytes_to_base64(digest, MHASH384_SIZE));
117+ }
118+ else
119+ {
120+ return bytes_to_hex(digest, MHASH384_SIZE, options.lower_case);
121+ }
122+}
123+
124+/*
109125 * Parse command-line options
110126 */
111127 static opmode_t parse_options(int &arg_offset, options_t &options, const int argc, const CHAR_T *const *const argv)
@@ -131,7 +147,11 @@ static opmode_t parse_options(int &arg_offset, options_t &options, const int arg
131147 }
132148 else if (!STRICMP(argstr, STR("base64")))
133149 {
134- options.base64 = true;
150+ options.base_enc = (options.base_enc != 1) ? (options.base_enc + 1) : options.base_enc;
151+ }
152+ else if (!STRICMP(argstr, STR("base85")))
153+ {
154+ options.base_enc = (options.base_enc != 2) ? (options.base_enc + 2) : options.base_enc;
135155 }
136156 else if(!STRICMP(argstr, STR("lower-case")))
137157 {
@@ -168,10 +188,17 @@ static opmode_t parse_options(int &arg_offset, options_t &options, const int arg
168188 ++arg_offset;
169189 }
170190
171- if (options.base64 && options.lower_case)
191+ if (options.base_enc > 2)
192+ {
193+ print_logo();
194+ FPUTS(STR("Error: Options \"--base64\" and \"--base85\" are mutually exclusive!\n"), stderr);
195+ fflush(stderr);
196+ return MODE_UNKNOWN;
197+ }
198+ else if (options.base_enc && options.lower_case)
172199 {
173200 print_logo();
174- FPUTS(STR("Error: Options \"--base64\" and \"--lower-case\" are mutually exclusive!\n"), stderr);
201+ FPRINTF(stderr, STR("Error: Options \"--%") PRI_CHAR STR("\" and \"--lower-case\" are mutually exclusive!\n"), (options.base_enc > 1U) ? STR("base85") : STR("base64"));
175202 fflush(stderr);
176203 return MODE_UNKNOWN;
177204 }
@@ -230,10 +257,9 @@ static bool process_file(const CHAR_T *const file_name, const options_t options)
230257 if(!ferror(input))
231258 {
232259 const uint8_t *const digest = mhash384.finish();
233- const std::string string = options.base64 ? bytes_to_base64(digest, MHASH384_SIZE) : bytes_to_hex(digest, MHASH384_SIZE, options.lower_case);
234260 const CHAR_T *const source_name = file_name ? file_name : STR("-");
235261 const CHAR_T *const format = options.short_format ? STR("%") PRI_char STR("\n") : STR("%") PRI_char STR(" %") PRI_CHAR STR("\n");
236- FPRINTF(stdout, format, string.c_str(), source_name);
262+ FPRINTF(stdout, format, encode_digest(digest, options).c_str(), source_name);
237263 fflush(stdout);
238264 }
239265 else
--- a/frontend/src/self_test.cpp
+++ b/frontend/src/self_test.cpp
@@ -154,6 +154,21 @@ static bool read_line(FILE *const input, char *const line, const int max_count,
154154 }
155155
156156 /*
157+ * Encode digest string
158+ */
159+static std::string encode_digest(const uint8_t *const digest, const options_t &options)
160+{
161+ if (options.base_enc)
162+ {
163+ return ((options.base_enc > 1U) ? bytes_to_base85(digest, MHASH384_SIZE) : bytes_to_base64(digest, MHASH384_SIZE));
164+ }
165+ else
166+ {
167+ return bytes_to_hex(digest, MHASH384_SIZE, options.lower_case);
168+ }
169+}
170+
171+/*
157172 * Compute hash and compare against reference
158173 */
159174 static bool test_string(const uint32_t count, const char *const text, const uint8_t *const expected, const options_t &options)
@@ -167,9 +182,7 @@ static bool test_string(const uint32_t count, const char *const text, const uint
167182 const uint8_t *const digest = mhash384.finish();
168183 const bool success = (!memcmp(digest, expected, MHASH384_SIZE));
169184
170- const std::string string = options.base64 ? bytes_to_base64(digest, MHASH384_SIZE) : bytes_to_hex(digest, MHASH384_SIZE, options.lower_case);
171- const CHAR_T *const result = success ? STR("OK") : STR("Error!");
172- FPRINTF(stderr, STR("%") PRI_char STR(" - %") PRI_CHAR STR("\n"), string.c_str(), result);
185+ FPRINTF(stderr, STR("%") PRI_char STR(" - %") PRI_CHAR STR("\n"), encode_digest(digest, options).c_str(), success ? STR("OK") : STR("Error!"));
173186
174187 fflush(stderr);
175188 return success;
@@ -178,14 +191,12 @@ static bool test_string(const uint32_t count, const char *const text, const uint
178191 /*
179192 * Compute hash and append to hashset
180193 */
181-static bool append_string(UnorderedHashSet &hash_set, std::vector<std::array<uint64_t,256U>> &stats, const char *const text, const bool base64, const bool lower_case)
194+static bool append_string(UnorderedHashSet &hash_set, std::vector<std::array<uint64_t,256U>> &stats, const char *const text, const options_t &options)
182195 {
183196 std::array<uint8_t, MHASH384_SIZE> digest;
184197 mhash384_compute(digest.data(), reinterpret_cast<const uint8_t*>(text), strlen(text));
185198
186- const std::string string = base64 ? bytes_to_base64(digest.data(), MHASH384_SIZE) : bytes_to_hex(digest.data(), MHASH384_SIZE, lower_case);
187- FPRINTF(stderr, STR("%") PRI_char STR("\n"), string.c_str());
188-
199+ FPRINTF(stderr, STR("%") PRI_char STR("\n"), encode_digest(digest.data(), options).c_str());
189200 for(size_t i = 0U; i < MHASH384_SIZE; ++i)
190201 {
191202 stats[i][digest[i]]++;
@@ -263,7 +274,7 @@ bool stress_test(const CHAR_T *const file_name, const options_t &options)
263274 /*FPRINTF(stderr, STR("\"%") PRI_char STR("\"\n"), line);*/
264275 if(line[0U])
265276 {
266- if(!append_string(hash_set, stats, line, options.base64, options.lower_case))
277+ if(!append_string(hash_set, stats, line, options))
267278 {
268279 success = false;
269280 if(!options.keep_going)
--- a/frontend/src/utils.cpp
+++ b/frontend/src/utils.cpp
@@ -96,3 +96,67 @@ std::string bytes_to_base64(const uint8_t *const data, const size_t len)
9696
9797 return result.str();
9898 }
99+
100+/*
101+ * Convert byte array to Base85-string
102+ * implementation based on code created by Doug Currie <https://github.com/dcurrie/ascii85>
103+ */
104+std::string bytes_to_base85(const uint8_t *const data, const size_t len)
105+{
106+ static const char BASE_CHAR = '!';
107+
108+ size_t pos = 0U;
109+ std::ostringstream result;
110+ char temp[6U];
111+ memset(temp, 0, sizeof(char) * 6U);
112+
113+ while (pos < len)
114+ {
115+ uint32_t chunk;
116+ size_t n = len - pos;
117+
118+ if (n >= 4U)
119+ {
120+ chunk = (((uint32_t)data[pos++]) << 24U);
121+ chunk |= (((uint32_t)data[pos++]) << 16U);
122+ chunk |= (((uint32_t)data[pos++]) << 8U);
123+ chunk |= (((uint32_t)data[pos++]));
124+ }
125+ else
126+ {
127+ chunk = (((uint32_t)data[pos++]) << 24U);
128+ if (pos < len)
129+ {
130+ chunk |= (((uint32_t)data[pos++]) << 16U);
131+ if (pos < len)
132+ {
133+ chunk |= (((uint32_t)data[pos++]) << 8U);
134+ if (pos < len)
135+ {
136+ chunk |= (((uint32_t)data[pos++]));
137+ }
138+ }
139+ }
140+ }
141+
142+ if(chunk || (n < 4U))
143+ {
144+ temp[4U] = ((char)(BASE_CHAR + (chunk % 85U)));
145+ chunk /= 85U;
146+ temp[3U] = ((char)(BASE_CHAR + (chunk % 85U)));
147+ chunk /= 85U;
148+ temp[2U] = ((char)(BASE_CHAR + (chunk % 85U)));
149+ chunk /= 85U;
150+ temp[1U] = ((char)(BASE_CHAR + (chunk % 85U)));
151+ chunk /= 85U;
152+ temp[0U] = ((char)(BASE_CHAR + chunk));
153+ result << temp;
154+ }
155+ else
156+ {
157+ result << 'z'; /*encode z for zero*/
158+ }
159+ }
160+
161+ return result.str();
162+}
--- a/frontend/src/utils.h
+++ b/frontend/src/utils.h
@@ -29,5 +29,6 @@
2929 const CHAR_T * get_basename(const CHAR_T *const path);
3030 std::string bytes_to_hex(const uint8_t *const data, const size_t len, const bool lower_case);
3131 std::string bytes_to_base64(const uint8_t *const data, const size_t len);
32+std::string bytes_to_base85(const uint8_t *const data, const size_t len);
3233
3334 #endif /*INC_MHASH384_UTILS_H*/
Show on old repository browser