]> gitweb.hamatoma.de Git - crepublib/commitdiff
MD5 appendHexDump
authorhama <hama@siduction.net>
Sun, 1 Feb 2015 18:22:53 +0000 (19:22 +0100)
committerhama <hama@siduction.net>
Sun, 1 Feb 2015 18:22:53 +0000 (19:22 +0100)
base/ReByteBuffer.cpp
base/ReByteBuffer.hpp
cunit/cuReByteBuffer.cpp
cunit/cuReMD5.cpp
cunit/testall.cpp
math/ReMD5.cpp
math/ReMD5.hpp

index acf4992168d07d9e1ca345ff295f3fc7150a2ba1..d8d3d774f35f4b72c1ff11125160ecaa1e37685c 100644 (file)
@@ -168,6 +168,83 @@ ReByteBuffer&  ReByteBuffer::appendInt(int number, const char* format){
 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
index a3bcc5ba09350492acb239df90f2b5ac17d96567..9dcc9f99445c671b09e0314258417ea378d39ded 100644 (file)
@@ -46,6 +46,10 @@ public:
 public:
        ReByteBuffer& append(const Byte* source, size_t length = -1);
        ReByteBuffer& append(const ReByteBuffer& source);
+       ReByteBuffer& appendHexDump(const char* data, size_t length = -1,
+               int offset = 0, int bytePerLine = 16,
+               const char* offsetFormat = "%04x: ", bool withAscii = true,
+               int groupWidth = 1, int gapBehind = -1, const char* separator = " | ");
        ReByteBuffer& appendInt(int number, const char* format = "%d");
        ReByteBuffer& appendMilliSec(int time, int minLength = 5);
        /** @brief Returns the n-th byte of the internal buffer.
index 982d3fdf0312567ccfbf9db957614c7add7fb189..d49fcec94af5af33da135ee1ab0312a2cfc55269 100644 (file)
@@ -15,6 +15,7 @@ public:
        }
 private:
        void run(){
+               testHexDump();
                testFill();
                testAppendMilliSec();
                testSetDelta();
@@ -36,6 +37,26 @@ private:
                testSplice();
                testReplace();
        }
+       void testHexDump(){
+               ReByteBuffer buf;
+               /* appendHexDump(const char* data, size_t length, int offset = 0, int bytePerLine = 16,
+               const char* offsetFormat = "%04x ", bool withAscii = true,
+               int groupWidth = 1, int gapBehind = -1, const char* separator = " | ");
+               */
+               buf.appendHexDump("abcdefghijklmnopq");
+               checkEqu("0000: 61 62 63 64 65 66 67 68  69 6a 6b 6c 6d 6e 6f 70 | abcdefgh ijklmnop\n"
+                                "0010: 71                                               | q                \n",
+                                buf.str());
+               buf.setLength(0).appendHexDump("abcdefghijklmnopq", 16);
+               checkEqu("0000: 61 62 63 64 65 66 67 68  69 6a 6b 6c 6d 6e 6f 70 | abcdefgh ijklmnop\n",
+                                buf.str());
+               buf.setLength(0).appendHexDump("\t\nü23456789 1234567890", -1, 20, 8, "%3d: ", true,
+                       2, 3, NULL);
+               printf("%s", buf.str());
+               checkEqu(" 20: 090a ffffffc3 ffffffbc 3233  3435... .23 45\n"
+                       " 28: 3637 38 39 2031  3233678 9 1 23\n"
+                       " 36: 3435 36 37 3839  30  456 789 0 \n", buf.str());
+       }
        void testFill(){
                ReByteBuffer buf;
                buf.fill('=', 0, 3);
index c3fd45615ed2021d0fb9ec5ec744c688c7389c13..3bac001c90bea57a1761ec68488b7a66a660152c 100644 (file)
@@ -18,6 +18,7 @@
 
 #include "base/rebase.hpp"
 #include "math/remath.hpp"
+//#include "math/md5.hpp"
 
 class TestReMd5 : public ReTestUnit {
 public:
@@ -26,13 +27,28 @@ public:
        }
 private:
        void run(){
+               testOld();
                testBase();
        }
+       void testOld(){
+#if 0
+               MD5 md5;
+               md5.update("", 0);
+               md5.finalize();
+               std::string dig = md5.hexdigest();
+               const char* dig2 = (const char*) dig.c_str();
+               dig2++;
+#endif
+       }
        void testBase(){
                ReMD5 md5;
                md5.update((const uint8_t*)"", 0);
                checkEqu("d41d8cd98f00b204e9800998ecf8427e",
                        md5.hexDigest().str());
+               md5.reset();
+               md5.update((const uint8_t*)"01234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVEXYZ01234567890\n", -1);
+               checkEqu("c0a278c051a6898f6ad05da7fa80a1c4",
+                       md5.hexDigest().str());
        }
 };
 extern void testReMD5(void);
index 844d604a7998d91773de6bbee2319b7debee3426..2634bb6d9650c8cbf909034df051a3e1e0f74353 100644 (file)
@@ -13,8 +13,8 @@
 #endif
 
 void testBase(){
-       extern void testReProgramArgs(void);
-       testReProgramArgs();
+       extern void testReByteBuffer();
+       testReByteBuffer();
 
        extern void testReTestUnit();
        //testReTestUnit();
@@ -70,8 +70,8 @@ void testMath(){
 void testAll(){
        try
        {
-               testMath();
-               
+               testBase();
+
                testOs();
                testBase();
                testMath();
index 4621c315275e1937a6d15aca7f5724f5dcad41d9..403522e03597d17be41503195cd79edbd9916907 100644 (file)
@@ -7,6 +7,7 @@
 
 #include "base/rebase.hpp"
 #include "math/remath.hpp"
+
 #define __LITTLE_ENDIAN__
 
 const int ReMD5::m_s[64] = {
@@ -15,7 +16,7 @@ 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,
@@ -81,7 +82,6 @@ const uint8_t* ReMD5::digest(){
 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.
@@ -94,7 +94,7 @@ void ReMD5::finalize(){
        // 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;
@@ -102,21 +102,21 @@ void ReMD5::finalize(){
        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)
@@ -126,10 +126,9 @@ void ReMD5::finalize(){
        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);
@@ -157,17 +156,18 @@ const ReByteBuffer& ReMD5::hexDigest(){
  * 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
@@ -175,23 +175,23 @@ void ReMD5::processChunk(const uint8_t block[64]){
 #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
@@ -202,11 +202,11 @@ void ReMD5::processChunk(const uint8_t block[64]){
                        // 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;
@@ -230,6 +230,8 @@ void ReMD5::reset(){
        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.
@@ -238,6 +240,8 @@ void ReMD5::reset(){
  * @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){
@@ -255,15 +259,19 @@ void ReMD5::update(const uint8_t* block, int blockLength){
                }
        }
        // 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;
+               }
        }
 }
 
index 7c885ee20986a7683db2b5fdaf69cd33cb538686..1294bc360b83d0be6c3fb7e8ae6ffce944459c0e 100644 (file)
@@ -35,15 +35,17 @@ private:
        uint8_t m_waiting[64+64];
        int m_lengthWaiting;
        // total count of input bytes:
-       int m_length;
-       int m_a0;
-       int m_b0;
-       int m_c0;
-       int m_d0;
+       uint32_t m_length;
+       uint32_t m_a0;
+       uint32_t m_b0;
+       uint32_t m_c0;
+       uint32_t m_d0;
        bool m_finalized;
 private:
+       // number of shifts per round:
        static const int m_s[64];
-       static const int m_K[64];
+       // Constants:
+       static const uint32_t m_K[64];
 };
 
 #endif /* MATH_REMD5_HPP_ */