1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-21 10:26:06 +03:00

Add tests for MD5Builder, reformat and clean up code

This commit is contained in:
Ivan Grokhotkov 2016-06-13 12:47:33 +08:00
parent 3640757692
commit 063e4cc88f
8 changed files with 484 additions and 62 deletions

View File

@ -1,77 +1,102 @@
#include "Arduino.h" #include <Arduino.h>
#include "md5.h" #include <MD5Builder.h>
#include "MD5Builder.h"
#define hex_char_to_byte(c) (((c)>='a'&&(c)<='f')?((c)-87):((c)>='A'&&(c)<='F')?((c)-55):((c)>='0'&&(c)<='9')?((c)-48):0) uint8_t hex_char_to_byte(uint8_t c)
{
void MD5Builder::begin(void){ return (c >= 'a' && c <= 'f') ? (c - ((uint8_t)'a' - 0xa)) :
memset(_buf, 0x00, 16); (c >= 'A' && c <= 'F') ? (c - ((uint8_t)'A' - 0xA)) :
MD5Init(&_ctx); (c >= '0'&& c<= '9') ? (c - (uint8_t)'0') : 0;
} }
void MD5Builder::add(uint8_t * data, uint16_t len){ void MD5Builder::begin(void)
MD5Update(&_ctx, data, len); {
memset(_buf, 0x00, 16);
MD5Init(&_ctx);
} }
void MD5Builder::addHexString(const char * data){ void MD5Builder::add(uint8_t * data, uint16_t len)
uint16_t i, len = strlen(data); {
uint8_t * tmp = (uint8_t*)malloc(len/2); MD5Update(&_ctx, data, len);
if(tmp == NULL)
return;
for(i=0; i<len; i+=2) tmp[i/2] = (hex_char_to_byte(data[i]) & 0x0F) << 4 | (hex_char_to_byte(data[i+1]) & 0x0F);
add(tmp, len/2);
free(tmp);
} }
bool MD5Builder::addStream(Stream & stream, const size_t maxLen) { void MD5Builder::addHexString(const char * data)
const int buf_size = 512; {
int maxLengthLeft = maxLen; uint16_t i, len = strlen(data);
uint8_t * buf = (uint8_t*) malloc(buf_size); uint8_t * tmp = (uint8_t*)malloc(len/2);
if(tmp == NULL) {
return;
}
for(i=0; i<len; i+=2) {
uint8_t high = hex_char_to_byte(data[i]);
uint8_t low = hex_char_to_byte(data[i+1]);
tmp[i/2] = (high & 0x0F) << 4 | (low & 0x0F);
}
add(tmp, len/2);
free(tmp);
}
bool MD5Builder::addStream(Stream & stream, const size_t maxLen)
{
const int buf_size = 512;
int maxLengthLeft = maxLen;
uint8_t * buf = (uint8_t*) malloc(buf_size);
if(!buf) {
return false;
}
if(buf) {
int bytesAvailable = stream.available(); int bytesAvailable = stream.available();
while((bytesAvailable > 0) && (maxLengthLeft > 0)) { while((bytesAvailable > 0) && (maxLengthLeft > 0)) {
// determine number of bytes to read // determine number of bytes to read
int readBytes = bytesAvailable; int readBytes = bytesAvailable;
if(readBytes > maxLengthLeft) readBytes = maxLengthLeft ; // read only until max_len if(readBytes > maxLengthLeft) {
if(readBytes > buf_size) readBytes = buf_size; // not read more the buffer can handle readBytes = maxLengthLeft ; // read only until max_len
}
if(readBytes > buf_size) {
readBytes = buf_size; // not read more the buffer can handle
}
// read data and check if we got something // read data and check if we got something
int numBytesRead = stream.readBytes(buf, readBytes); int numBytesRead = stream.readBytes(buf, readBytes);
if(numBytesRead< 1) return false; if(numBytesRead< 1) {
return false;
}
// Update MD5 with buffer payload // Update MD5 with buffer payload
MD5Update(&_ctx, buf, numBytesRead); MD5Update(&_ctx, buf, numBytesRead);
delay(0); // time for network streams yield(); // time for network streams
// update available number of bytes // update available number of bytes
maxLengthLeft -= numBytesRead; maxLengthLeft -= numBytesRead;
bytesAvailable = stream.available(); bytesAvailable = stream.available();
} }
printf("ba: %d mll: %d\n", bytesAvailable, maxLengthLeft);
free(buf); free(buf);
return true; return true;
} else {
return false;
}
} }
void MD5Builder::calculate(void){ void MD5Builder::calculate(void)
MD5Final(_buf, &_ctx); {
MD5Final(_buf, &_ctx);
} }
void MD5Builder::getBytes(uint8_t * output){ void MD5Builder::getBytes(uint8_t * output)
memcpy(output, _buf, 16); {
memcpy(output, _buf, 16);
} }
void MD5Builder::getChars(char * output){ void MD5Builder::getChars(char * output)
for(uint8_t i = 0; i < 16; i++) {
sprintf(output + (i * 2), "%02x", _buf[i]); for(uint8_t i = 0; i < 16; i++) {
sprintf(output + (i * 2), "%02x", _buf[i]);
}
} }
String MD5Builder::toString(void){ String MD5Builder::toString(void)
char out[33]; {
getChars(out); char out[33];
return String(out); getChars(out);
return String(out);
} }

View File

@ -21,7 +21,8 @@
#ifndef __ESP8266_MD5_BUILDER__ #ifndef __ESP8266_MD5_BUILDER__
#define __ESP8266_MD5_BUILDER__ #define __ESP8266_MD5_BUILDER__
#include "Arduino.h" #include <WString.h>
#include <Stream.h>
#include "md5.h" #include "md5.h"
class MD5Builder { class MD5Builder {

View File

@ -25,15 +25,14 @@
class StreamString: public Stream, public String { class StreamString: public Stream, public String {
public:
size_t write(const uint8_t *buffer, size_t size) override;
size_t write(uint8_t data) override;
size_t write(const uint8_t *buffer, size_t size); int available() override;
size_t write(uint8_t data); int read() override;
int peek() override;
int available(); void flush() override;
int read();
int peek();
void flush();
}; };

View File

@ -1,9 +1,9 @@
#ifndef ESP8266UPDATER_H #ifndef ESP8266UPDATER_H
#define ESP8266UPDATER_H #define ESP8266UPDATER_H
#include "Arduino.h" #include <Arduino.h>
#include "flash_utils.h" #include <flash_utils.h>
#include "MD5Builder.h" #include <MD5Builder.h>
#define UPDATE_ERROR_OK (0) #define UPDATE_ERROR_OK (0)
#define UPDATE_ERROR_WRITE (1) #define UPDATE_ERROR_WRITE (1)

View File

@ -1,4 +1,3 @@
OBJECT_DIRECTORY := obj
BINARY_DIRECTORY := bin BINARY_DIRECTORY := bin
OUTPUT_BINARY := $(BINARY_DIRECTORY)/host_tests OUTPUT_BINARY := $(BINARY_DIRECTORY)/host_tests
CORE_PATH := ../../cores/esp8266 CORE_PATH := ../../cores/esp8266
@ -18,6 +17,7 @@ CORE_CPP_FILES := $(addprefix $(CORE_PATH)/,\
FS.cpp \ FS.cpp \
spiffs_api.cpp \ spiffs_api.cpp \
pgmspace.cpp \ pgmspace.cpp \
MD5Builder.cpp \
) )
CORE_C_FILES := $(addprefix $(CORE_PATH)/,\ CORE_C_FILES := $(addprefix $(CORE_PATH)/,\
@ -35,6 +35,10 @@ MOCK_CPP_FILES := $(addprefix common/,\
WMath.cpp \ WMath.cpp \
) )
MOCK_C_FILES := $(addprefix common/,\
md5.c \
)
INC_PATHS += $(addprefix -I, \ INC_PATHS += $(addprefix -I, \
common \ common \
$(CORE_PATH) \ $(CORE_PATH) \
@ -43,18 +47,23 @@ INC_PATHS += $(addprefix -I, \
TEST_CPP_FILES := \ TEST_CPP_FILES := \
fs/test_fs.cpp \ fs/test_fs.cpp \
core/test_pgmspace.cpp \ core/test_pgmspace.cpp \
core/test_md5builder.cpp \
CXXFLAGS += -std=c++11 -Wall -coverage -O0
CFLAGS += -std=c99 -Wall -coverage -O0 CXXFLAGS += -std=c++11 -Wall -coverage -O0 -fno-common
CFLAGS += -std=c99 -Wall -coverage -O0 -fno-common
LDFLAGS += -coverage -O0 LDFLAGS += -coverage -O0
remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1)))) remduplicates = $(strip $(if $1,$(firstword $1) $(call remduplicates,$(filter-out $(firstword $1),$1))))
C_SOURCE_FILES = $(CORE_C_FILES) C_SOURCE_FILES = $(MOCK_C_FILES) $(CORE_C_FILES)
CPP_SOURCE_FILES = $(MOCK_CPP_FILES) $(CORE_CPP_FILES) $(TEST_CPP_FILES) CPP_SOURCE_FILES = $(MOCK_CPP_FILES) $(CORE_CPP_FILES) $(TEST_CPP_FILES)
C_OBJECTS = $(C_SOURCE_FILES:.c=.c.o) C_OBJECTS = $(C_SOURCE_FILES:.c=.c.o)
CPP_OBJECTS = $(CPP_SOURCE_FILES:.cpp=.cpp.o) CPP_OBJECTS_CORE = $(MOCK_CPP_FILES:.cpp=.cpp.o) $(CORE_CPP_FILES:.cpp=.cpp.o)
CPP_OBJECTS_TESTS = $(TEST_CPP_FILES:.cpp=.cpp.o)
CPP_OBJECTS = $(CPP_OBJECTS_CORE) $(CPP_OBJECTS_TESTS)
OBJECTS = $(C_OBJECTS) $(CPP_OBJECTS) OBJECTS = $(C_OBJECTS) $(CPP_OBJECTS)
COVERAGE_FILES = $(OBJECTS:.o=.gc*) COVERAGE_FILES = $(OBJECTS:.o=.gc*)
@ -95,5 +104,9 @@ $(C_OBJECTS): %.c.o: %.c
$(CPP_OBJECTS): %.cpp.o: %.cpp $(CPP_OBJECTS): %.cpp.o: %.cpp
$(CXX) $(CXXFLAGS) $(INC_PATHS) -c -o $@ $< $(CXX) $(CXXFLAGS) $(INC_PATHS) -c -o $@ $<
$(OUTPUT_BINARY): $(BINARY_DIRECTORY) $(OBJECTS) $(BINARY_DIRECTORY)/core.a: $(C_OBJECTS) $(CPP_OBJECTS_CORE)
$(CXX) $(LDFLAGS) $(OBJECTS) $(LIBS) -o $(OUTPUT_BINARY) ar -rcu $@ $(C_OBJECTS) $(CPP_OBJECTS_CORE)
ranlib -c $@
$(OUTPUT_BINARY): $(BINARY_DIRECTORY) $(CPP_OBJECTS_TESTS) $(BINARY_DIRECTORY)/core.a
$(CXX) $(LDFLAGS) $(CPP_OBJECTS_TESTS) $(BINARY_DIRECTORY)/core.a $(LIBS) -o $(OUTPUT_BINARY)

View File

@ -35,3 +35,7 @@ extern "C" void yield()
extern "C" void __panic_func(const char* file, int line, const char* func) { extern "C" void __panic_func(const char* file, int line, const char* func) {
abort(); abort();
} }
extern "C" void delay(unsigned long ms)
{
}

307
tests/host/common/md5.c Normal file
View File

@ -0,0 +1,307 @@
/*
* Copyright (c) 2007, Cameron Rich
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* * Neither the name of the axTLS project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* This file implements the MD5 algorithm as defined in RFC1321
*/
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#define EXP_FUNC extern
#define STDCALL
#define MD5_SIZE 16
typedef struct
{
uint32_t state[4]; /* state (ABCD) */
uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
uint8_t buffer[64]; /* input buffer */
} MD5_CTX;
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
/* ----- static functions ----- */
static void MD5Transform(uint32_t state[4], const uint8_t block[64]);
static void Encode(uint8_t *output, uint32_t *input, uint32_t len);
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len);
static const uint8_t PADDING[64] =
{
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits. */
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation. */
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (uint32_t)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/**
* MD5 initialization - begins an MD5 operation, writing a new ctx.
*/
EXP_FUNC void STDCALL MD5Init(MD5_CTX *ctx)
{
ctx->count[0] = ctx->count[1] = 0;
/* Load magic initialization constants.
*/
ctx->state[0] = 0x67452301;
ctx->state[1] = 0xefcdab89;
ctx->state[2] = 0x98badcfe;
ctx->state[3] = 0x10325476;
}
/**
* Accepts an array of octets as the next portion of the message.
*/
EXP_FUNC void STDCALL MD5Update(MD5_CTX *ctx, const uint8_t * msg, int len)
{
uint32_t x;
int i, partLen;
/* Compute number of bytes mod 64 */
x = (uint32_t)((ctx->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((ctx->count[0] += ((uint32_t)len << 3)) < ((uint32_t)len << 3))
ctx->count[1]++;
ctx->count[1] += ((uint32_t)len >> 29);
partLen = 64 - x;
/* Transform as many times as possible. */
if (len >= partLen)
{
memcpy(&ctx->buffer[x], msg, partLen);
MD5Transform(ctx->state, ctx->buffer);
for (i = partLen; i + 63 < len; i += 64)
MD5Transform(ctx->state, &msg[i]);
x = 0;
}
else
i = 0;
/* Buffer remaining input */
memcpy(&ctx->buffer[x], &msg[i], len-i);
}
/**
* Return the 128-bit message digest into the user's array
*/
EXP_FUNC void STDCALL MD5Final(uint8_t *digest, MD5_CTX *ctx)
{
uint8_t bits[8];
uint32_t x, padLen;
/* Save number of bits */
Encode(bits, ctx->count, 8);
/* Pad out to 56 mod 64.
*/
x = (uint32_t)((ctx->count[0] >> 3) & 0x3f);
padLen = (x < 56) ? (56 - x) : (120 - x);
MD5Update(ctx, PADDING, padLen);
/* Append length (before padding) */
MD5Update(ctx, bits, 8);
/* Store state in digest */
Encode(digest, ctx->state, MD5_SIZE);
}
/**
* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform(uint32_t state[4], const uint8_t block[64])
{
uint32_t a = state[0], b = state[1], c = state[2],
d = state[3], x[MD5_SIZE];
Decode(x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
}
/**
* Encodes input (uint32_t) into output (uint8_t). Assumes len is
* a multiple of 4.
*/
static void Encode(uint8_t *output, uint32_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
{
output[j] = (uint8_t)(input[i] & 0xff);
output[j+1] = (uint8_t)((input[i] >> 8) & 0xff);
output[j+2] = (uint8_t)((input[i] >> 16) & 0xff);
output[j+3] = (uint8_t)((input[i] >> 24) & 0xff);
}
}
/**
* Decodes input (uint8_t) into output (uint32_t). Assumes len is
* a multiple of 4.
*/
static void Decode(uint32_t *output, const uint8_t *input, uint32_t len)
{
uint32_t i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((uint32_t)input[j]) | (((uint32_t)input[j+1]) << 8) |
(((uint32_t)input[j+2]) << 16) | (((uint32_t)input[j+3]) << 24);
}

View File

@ -0,0 +1,73 @@
/*
test_md5builder.cpp - MD5Builder tests
Copyright © 2016 Ivan Grokhotkov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
*/
#include <catch.hpp>
#include <string.h>
#include <MD5Builder.h>
#include <StreamString.h>
TEST_CASE("MD5Builder::add works as expected", "[core][MD5Builder]")
{
MD5Builder builder;
builder.begin();
builder.add("short");
builder.calculate();
REQUIRE(builder.toString() == "4f09daa9d95bcb166a302407a0e0babe");
builder.begin();
builder.add("longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong");
builder.calculate();
REQUIRE(builder.toString() == "9edb67f2b22c604fab13e2fd1d6056d7");
}
TEST_CASE("MD5Builder::addHexString works as expected", "[core][MD5Builder]")
{
MD5Builder builder;
builder.begin();
builder.addHexString("1234567890abcdeffedcba98765432106469676974616c7369676e61747572656170706c69636174696f6e73");
builder.calculate();
REQUIRE(builder.toString() == "47b937a6f9f12a4c389fa5854e023efb");
}
TEST_CASE("MD5Builder::addStream works", "[core][MD5Builder]")
{
MD5Builder builder;
const char* str = "MD5Builder::addStream_works_longlonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglonglong";
{
StreamString stream;
stream.print(str);
builder.begin();
builder.addStream(stream, stream.available());
builder.calculate();
REQUIRE(builder.toString() == "bc4a2006e9d7787ee15fe3d4ef9cdb46");
}
{
StreamString stream;
stream.print(str);
builder.begin();
builder.addStream(stream, 20);
builder.calculate();
REQUIRE(builder.toString() == "c9ad2a3d64b9a877831a67b3bfd34228");
}
{
StreamString stream;
stream.print(str);
builder.begin();
builder.addStream(stream, 120);
builder.calculate();
REQUIRE(builder.toString() == "bc4a2006e9d7787ee15fe3d4ef9cdb46");
}
}