wezel *RBDELFIX(wezel*root, wezel *x){ wezel *w; while(x!=root && x->kolor==BLACK){ if(x==x->p->left){ w=x->p->right; if(w->kolor==RED){ //PRZYPADEK 1 w->kolor=BLACK; //PRZYPADEK 1 x->p->kolor=RED; //PRZYPADEK 1 root=LEFTROTATE(root,x->p); //PRZYPADEK 1 w=x->p->right; } if(w->left->kolor==BLACK && w->right->kolor==BLACK){ w->kolor=RED; //PRZYPADEK 2 x=x->p; //PRZYPADEK 2 } else{ if(w->right->kolor==BLACK){ w->left->kolor=BLACK; //PRZYPADEK 3 w->kolor=RED; //PRZYPADEK 3 root=RIGHTROTATE(root,w);//PRZYPADEK 3 w=x->p->right; //PRZYPADEK 3 } w->kolor=x->p->kolor; //PRZYPADEK 4 x->p->kolor=BLACK; //PRZYPADEK 4 w->right->kolor=BLACK; //PRZYPADEK 4 root=LEFTROTATE(root,x->p); //PRZYPADEK 4 x=root; } } else{ w=x->p->left; if(w->kolor==RED){ w->kolor=BLACK; x->p->kolor=RED; root=RIGHTROTATE(root,x->p); w=x->p->left; } if(w->right->kolor==BLACK && w->left->kolor==BLACK){ w->kolor=RED; x=x->p; } else{ if(w->left->kolor==BLACK){ w->right->kolor=BLACK; w->kolor=RED; root=LEFTROTATE(root,w); w=x->p->left; } w->kolor=x->p->kolor; x->p->kolor=BLACK; w->left->kolor=BLACK; root=RIGHTROTATE(root,x->p); x=root; } } } x->kolor=BLACK; return root; }
wezel* RBFIX(wezel *root, wezel *z){ wezel *y; // printf("RBFIX dla (%d,%d)\n", root->key, z->key); while(root!=z && z->p->kolor==RED){ if(z->p == z->p->p->left){ // printf("ojciec %d jest po lewej stronie dziadka \n", z->key); y = z->p->p->right; if(y!= &NIL && y->kolor==RED){ z->p->kolor=BLACK; y->kolor=BLACK; z->p->p->kolor=RED; z = z->p->p; } else{ if(z==z->p->right){ z=z->p; root=LEFTROTATE(root,z); } z->p->kolor=BLACK; z->p->p->kolor=RED; root=RIGHTROTATE(root,z->p->p); } } else{ //printf("ojciec %d jest po prawej stronie dziadka \n", z->key); y = z->p->p->left; if(y!= &NIL && y->kolor==RED){ z->p->kolor=BLACK; y->kolor=BLACK; z->p->p->kolor=RED; z = z->p->p; } else { // printf("Po lewej stronie dziadka jest czarny wezel\n"); if(z==z->p->left){ // printf("%d jest lewym synem %d\n", z->key, z->p->key); z=z->p; root=RIGHTROTATE(root, z); } z->p->kolor=BLACK; z->p->p->kolor=RED; root=LEFTROTATE(root, z->p->p); } } } root->kolor = BLACK; return root; }
/* Produces the MD5 digest of the message stored at *message (length * message_len) and places the result in the 16-byte buffer at *hash */ void md5(const uint8_t *message, size_t message_len, uint8_t *hash) { /* 32-bit word interface to the hash output buffer */ uint32_t *hash32 = (uint32_t *)hash; /* Working buffer (padded message plus length) */ uint8_t buff[BUFF_LEN]; /* Note: All variables are unsigned 32 bit and wrap modulo 2^32 when * calculating. r specifies the per-round shift amounts */ uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; /* Magic numbers: */ uint32_t k[] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}; /* Starting value for hash */ hash32[0] = 0x67452301; hash32[1] = 0xefcdab89; hash32[2] = 0x98badcfe; hash32[3] = 0x10325476; /* Pad the message with zeros to the new buffer length */ memset(buff, 0, BUFF_LEN); memcpy(buff, message, message_len); /* Append a 1-bit to the end of the message. Not sure why */ buff[message_len] = 128; // write the "1" bit /* Append the length (in bits) to the end of the message */ uint32_t bits_len = 8*message_len; memcpy(buff + PADDED_MESSAGE_LEN, &bits_len, 4); /* Process the message in successive 512-bit chunks */ uint16_t offset; for(offset=0; offset < PADDED_MESSAGE_LEN; offset += (512/8)) { /* break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15 */ uint32_t *w = (uint32_t *) (buff + offset); /* Initialize hash value for this chunk */ uint32_t a = hash32[0]; uint32_t b = hash32[1]; uint32_t c = hash32[2]; uint32_t d = hash32[3]; /* Main loop for the chunk */ uint32_t i; for(i = 0; i<64; i++) { uint32_t f, g; if (i < 16) { f = (b & c) | ((~b) & d); g = i; } else if (i < 32) { f = (d & b) | ((~d) & c); g = (5*i + 1) % 16; } else if (i < 48) { f = b ^ c ^ d; g = (3*i + 5) % 16; } else { f = c ^ (b | (~d)); g = (7*i) % 16; } uint32_t temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); a = temp; } /* Add this chunk to the hash-in-progress */ hash32[0] += a; hash32[1] += b; hash32[2] += c; hash32[3] += d; } }
void md5(uint8_t *initial_msg, size_t initial_len) { // Message (to prepare) uint8_t *msg = NULL; int new_len; uint32_t bits_len; int offset; uint32_t *w; uint32_t a, b, c, d, i, f, g, temp; // Note: All variables are unsigned 32 bit and wrap modulo 2^32 when calculating // r specifies the per-round shift amounts const uint32_t r[] = {7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21}; // Initialize variables - simple count in nibbles: h0 = 0x67452301; h1 = 0xefcdab89; h2 = 0x98badcfe; h3 = 0x10325476; // Pre-processing: adding a single 1 bit //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.[37] */ // Pre-processing: padding with zeros //append "0" bit until message length in bit \u2261 448 (mod 512) //append length mod (2 pow 64) to message for(new_len = initial_len*8 + 1; new_len%512!=448; new_len++); new_len /= 8; msg = (uint8_t*)calloc(new_len + 64, 1); // also appends "0" bits // (we alloc also 64 extra bytes...) memcpy(msg, initial_msg, initial_len); msg[initial_len] = 128; // write the "1" bit bits_len = 8*initial_len; // note, we append the len memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer // Process the message in successive 512-bit chunks: //for each 512-bit chunk of message: for(offset=0; offset<new_len; offset += (512/8)) { // break chunk into sixteen 32-bit words w[j], 0 \u2264 j \u2264 15 w = (uint32_t *) (msg + offset); #ifdef USE_DEBUG printf("offset: %d %x\n", offset, offset); int j; for(j =0; j < 64; j++) printf("%x ", ((uint8_t *) w)[j]); puts(""); #endif // Initialize hash value for this chunk: a = h0; b = h1; c = h2; d = h3; // Main loop: for(i = 0; i<64; i++) { if (i < 16) { f = (b & c) | ((~b) & d); g = i; } else if (i < 32) { f = (d & b) | ((~d) & c); g = (5*i + 1) % 16; } else if (i < 48) { f = b ^ c ^ d; g = (3*i + 5) % 16; } else { f = c ^ (b | (~d)); g = (7*i) % 16; } temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); a = temp; } // Add this chunk's hash to result so far: h0 += a; h1 += b; h2 += c; h3 += d; } // cleanup free(msg); }
std::vector<uint32_t> Hash::digest() { uint8_t *msg = nullptr; // Initialize variables - simple count in nibbles: h[0] = 0x67452301; h[1] = 0xefcdab89; h[2] = 0x98badcfe; h[3] = 0x10325476; // Pre-processing: adding a single 1 bit //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.[37] */ // Pre-processing: padding with zeros //append "0" bit until message length in bit ≡ 448 (mod 512) //append length mod (2 pow 64) to message int new_len; for(new_len = this->str().length()*8 + 1; new_len%512!=448; new_len++); new_len /= 8; msg = (uint8_t*)calloc(new_len + 64, 1); // also appends "0" bits // (we alloc also 64 extra bytes...) memcpy(msg, this->str().c_str(), this->str().length()); msg[this->str().length()] = 128; // write the "1" bit uint32_t bits_len = 8*this->str().length(); // note, we append the len memcpy(msg + new_len, &bits_len, 4); // in bits at the end of the buffer // Process the message in successive 512-bit chunks: //for each 512-bit chunk of message: int offset; for(offset=0; offset<new_len; offset += (512/8)) { // break chunk into sixteen 32-bit words w[j], 0 ≤ j ≤ 15 uint32_t *w = (uint32_t *) (msg + offset); // Initialize hash value for this chunk: uint32_t a = h[0]; uint32_t b = h[1]; uint32_t c = h[2]; uint32_t d = h[3]; // Main loop: uint32_t i; for(i = 0; i<64; i++) { uint32_t f, g; if (i < 16) { f = (b & c) | ((~b) & d); g = i; } else if (i < 32) { f = (d & b) | ((~d) & c); g = (5*i + 1) % 16; } else if (i < 48) { f = b ^ c ^ d; g = (3*i + 5) % 16; } else { f = c ^ (b | (~d)); g = (7*i) % 16; } uint32_t temp = d; d = c; c = b; b = b + LEFTROTATE((a + f + k[i] + w[g]), r[i]); a = temp; } // Add this chunk's hash to result so far: h[0] += a; h[1] += b; h[2] += c; h[3] += d; } // cleanup free(msg); return h; }