ReByteBuffer& ReByteBuffer::append(const ReByteBuffer& source){
return append(source.str(), source.length());
}
+
+/**
+ * Appends a hexadecimal dump of a memory array.
+ *
+ * <pre>Example:
+ * <code>buffer.appendHex("01234567890abcde", -1, 0x10, 16, "%0x8x", 1, -1, " | ");
+ * </code>
+ * Buffer contains:
+ * 00000010 30 31 32 33 34 35 36 37 38 39 30 61 62 63 64 65 | 01234567890abcde
+ * </pre>
+ *
+ * @param data data to dump
+ * @param length length of <code>data</code>. -1: <code>strlen(data)</code>
+ * @param offset a format which is used to append a preceeding position
+ * of source. NULL: no offset is appended
+ * @param bytesPerLine number of bytes in one line. If length is greater more
+ * lines are appended
+ * @param offsetFormat NULL or the sprintf format of the offset, e.g. "0x04x "
+ * @param withAscii <code>true</code>: the data is interpreted as ASCII too
+ * @param groupWidth behind <code>groupWidth</code> hex bytes a ' ' is appended
+ * @param gapBehind behind <code>gapBehind</code> hex bytes a ' ' is appended<br>
+ * -1: <code>bytePerLine / 2</code>
+ * @param separator NULL or a string between hex area and ASCII area
+ */
+ReByteBuffer& ReByteBuffer::appendHexDump(const char* data, size_t length,
+ int offset, int bytesPerLine, const char* offsetFormat,
+ bool withAscii, int groupWidth, int gapBehind, const char* separator){
+ if (length == -1)
+ length = strlen(data);
+ if (gapBehind < 0)
+ gapBehind = bytesPerLine / 2;
+ ensureSize(32);
+ int offsetLength = 0;
+ if (offsetFormat != NULL){
+ snprintf(m_buffer, 31, offsetFormat, offset + length);
+ offsetLength = strlen(m_buffer);
+ }
+ ensureSize((length + bytesPerLine - 1) / bytesPerLine
+ * (4 + offsetLength + (gapBehind <= 0 ? 0 : bytesPerLine / gapBehind + 1)
+ + (separator == NULL ? 0 : strlen(separator))+ 1));
+ while(length > 0){
+ if (offsetFormat != NULL)
+ appendInt(offset, offsetFormat);
+ int ix;
+ for (ix = 0; ix < bytesPerLine; ix++){
+ if (ix < length)
+ appendInt(data[ix], "%02x");
+ else
+ append(" ");
+ if (ix < bytesPerLine - 1
+ && (groupWidth == 1 || ix % groupWidth == groupWidth - 1))
+ append(" ", 1);
+ if (ix < bytesPerLine - 1 && gapBehind > 0
+ && (gapBehind == 1 || ix % gapBehind == gapBehind - 1))
+ append(" ", 1);
+ }
+ if (withAscii){
+ if (separator != NULL)
+ append(separator, -1);
+ }
+ char cc;
+ for (ix = 0; ix < bytesPerLine; ix++){
+ if (ix < length)
+ appendInt( (cc = data[ix]) < ' ' || cc > 127 ? '.' : cc, "%c");
+ else
+ append(" ");
+ if (ix < bytesPerLine - 1 && gapBehind > 0
+ && (gapBehind == 1 || ix % gapBehind == gapBehind - 1))
+ append(" ", 1);
+ }
+ append("\n", 1);
+ length = length <= bytesPerLine ? 0 : length - bytesPerLine;
+ data += bytesPerLine;
+ offset += bytesPerLine;
+ }
+}
+
/** @brief Appends a time (given in milli seconds) as 'dd:HH:MM.mmm'.
*
* @param time the time (duration) in msec
#include "base/rebase.hpp"
#include "math/remath.hpp"
+
#define __LITTLE_ENDIAN__
const int ReMD5::m_s[64] = {
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
};
// for x in [1..64] : int(2**32 * sin(x))
-const int ReMD5::m_K[64] = {
+const uint32_t ReMD5::m_K[64] = {
0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
void ReMD5::finalize(){
uint8_t* block = m_waiting;
int blockLength = m_lengthWaiting;
-
// append "1" bit to message
// Notice: the input bytes are considered as bits strings,
// where the first bit is the most significant bit of the byte.
// 0 -> 56, 1 -> 55, 2 -> 54, ... 55 -> 1, 56 -> 0,
// 57 -> 63, 58 -> 62, ... 63 -> 57
int zeros = restLength <= 56 ? 56 - restLength : 120 - restLength;
- memset(block + blockLength + 1, 0, zeros);
+ memset(block + blockLength, 0, zeros);
blockLength += zeros;
//append original length in bits mod (2 pow 64) to message
uint64_t lengthBits = 8LL * m_length;
memcpy(block + blockLength, &lengthBits, 8);
blockLength += 8;
#else
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
- lengthBits >>= 4;
- block[blockLength++] = lengthBits & 0xff;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
+ lengthBits >>= 8;
+ block[blockLength++] = lengthBits;
#endif
processChunk(block);
if (blockLength > 64)
memcpy(m_digest + 4, &m_b0, 4);
memcpy(m_digest + 8, &m_c0, 4);
memcpy(m_digest + 12, &m_d0, 4);
- blockLength += 8;
#else
-#define oneWord(word, ix) m_digest[ix] = word; word >>= 4; \
- m_digest[ix + 1] = word; word >>= 4; m_digest[ix + 2] = word; word >>= 4; \
+#define oneWord(word, ix) m_digest[ix] = word; word >>= 8; \
+ m_digest[ix + 1] = word; word >>= 8; m_digest[ix + 2] = word; word >>= 8; \
m_digest[ix + 3] = word
oneWord(m_a0, 0);
oneWord(m_b0, 4);
* Processes a 512 bit block ("chunk").
*/
void ReMD5::processChunk(const uint8_t block[64]){
- int M[16];
+ uint32_t M[16];
// break chunk into sixteen 32-bit words M[j], 0 ≤ j ≤ 15
#ifdef __LITTLE_ENDIAN__
for (int ix = 0; ix < 16; ix++)
memcpy(&M[ix], block + ix * 4, 4);
#elif defined __BIG_ENDIAN__
for (int ix = 0; ix < 16; ix++){
- M[ix] = block[3];
- for (jj = 2; jj >= 0; jj--){
- M[ix] = (M[ix] << 4) + block[jj];
+ uint32_t x = block[3];
+ for (int jj = 2; jj >= 0; jj--){
+ x = (x << 8) + block[jj];
}
+ M[ix] = x;
block += 4;
}
#else
#endif
//Initialize hash value for this chunk:
- int A = m_a0;
- int B = m_b0;
- int C = m_c0;
- int D = m_d0;
+ uint32_t A = m_a0;
+ uint32_t B = m_b0;
+ uint32_t C = m_c0;
+ uint32_t D = m_d0;
//Main loop:
int F, g;
for (int i = 0; i < 64; i++){
- if (i <= 15){
+ if (i < 16){
// F := (B and C) or ((not B) and D)
F = (B & C) | (~ B & D);
g = i;
- } else if (i > 15 && i <= 31){
- // F := (D and B) or ((not D) and C)
- F = (D & B) | (~ D & C);
+ } else if (i < 32){
+ // F := (D and B) or (C and (not D))
+ F = (D & B) | (C & ~ D);
// g := (5×i + 1) mod 16
g = (5*i + 1) % 16;
- } else if (i > 31 && i <= 47){
+ } else if (i < 48){
// F := B xor C xor D
F = (B ^ C) ^ D;
// g := (3×i + 5) mod 16
// g := (7×i) mod 16
g = (7*i) % 16;
}
- int dTemp = D;
+ uint32_t dTemp = D;
D = C;
C = B;
// B := B + leftrotate((A + F + K[i] + M[g]), s[i])
- int x = (A + F + m_K[i] + M[g]) & 0xffffffff;
+ uint32_t x = (A + F + m_K[i] + M[g]);
int shift = m_s[i];
B += (x << shift) | (x >> (32 - shift));
A = dTemp;
memset(m_waiting, 0, sizeof m_waiting);
m_lengthWaiting = 0;
m_length = 0;
+ m_hexDigest.setLength(0);
+ m_finalized = false;
}
/**
* Processes a 64 byte block.
* @param blockLength the length of <code>block</code>
*/
void ReMD5::update(const uint8_t* block, int blockLength){
+ if (blockLength == -1)
+ blockLength = strlen((const char*) block);
// process the "waiting" input (incomplete chunk):
m_length += blockLength;
if (m_lengthWaiting > 0){
}
}
// process full 512 bit chunks (64 byte blocks):
- for (int ix = blockLength / 64; ix >= 0; ix--){
- processChunk(block);
- block += 64;
- }
- blockLength %= 64;
- if (blockLength != 0){
- assert(m_lengthWaiting == 0);
- memcpy(m_waiting, block, blockLength);
- m_lengthWaiting = blockLength;
+ if (blockLength > 0){
+ if (blockLength > 64){
+ for (int ix = blockLength / 64; ix >= 0; ix--){
+ processChunk(block);
+ block += 64;
+ }
+ }
+ blockLength %= 64;
+ if (blockLength != 0){
+ assert(m_lengthWaiting == 0);
+ memcpy(m_waiting, block, blockLength);
+ m_lengthWaiting = blockLength;
+ }
}
}