Redis Source Code Analysis (23)---CRC cyclic redundancy algorithm and Rand random number algorithm

Source: Internet
Author: User
Tags lua mul



Today began to study the Redis source code of some of the tools of the implementation, tool class in any language, the implementation of the principle of the algorithm should be the same, so you can take this opportunity to learn some of the more classical algorithms. For example, I see today the CRC cyclic redundancy check algorithm and rand random number generation algorithm.



CRC algorithm is the universal cyclic redundancy check algorithm. The basic idea of CRC is to use linear coding theory, in the transmitting side according to the K-bit binary code sequence to be transmitted, a certain rule to produce a verification of the supervisory code (CRC code) R bit, and attached to the information behind, constitute a new binary code sequence number of total (k+r) bit, and finally sent out. On the receiving end, the rules followed between the information code and the CRC code are checked to determine if there is an error in the transmission. The rule of 16-bit CRC code is that the number of binary sequences to be sent is shifted left by 16 bits (multiplied), divided by a polynomial, and the resulting remainder is both CRC code. The Redundancy check algorithm implemented in Redis is a byte-type algorithm;



The general description of the byte-type algorithm is: The CRC code of this byte, equal to the lower 8 bits of the previous byte CRC, left 8 bits, with the previous byte CRC right shift 8 bits of the same byte or the resulting CRC code XOR.
The byte-type algorithm is as follows:
1) The CRC Register Group is initialized to full "0" (0x0000). (Note: The CRC Register group initialization is all 1 o'clock, the last CRC should be reversed.) )
2) The CRC register group moves to the left 8 bits and is saved to the CRC Register Group.
3) The original CRC register group high 8 bits (right shift 8 bits) and the data byte is different or operation, to obtain a point to the value of the table index.
4) The table value referred to in the index is different from or calculated by the CRC Register Group.
5) data pointer plus 1, repeat step 2 if the data is not fully processed.
6) Draw the CRC.



Let's correspond to the code in Redis, fully compliant;




/* Crc64 cyclic redundancy algorithm, crc: base value 0, s: incoming content, l: content length */
Uint64_t crc64(uint64_t crc, const unsigned char *s, uint64_t l) {
     Uint64_t j;

     For (j = 0; j < l; j++) {
         Uint8_t byte = s[j];
         Crc = crc64_tab[(uint8_t)crc ^ byte] ^ (crc >> 8);
     }
     Return crc;
}
Redis built-in examples,
/* Test main */
/* Tested code */
#ifdef TEST_MAIN
#include <stdio.h>
Int main(void) {
     Printf("e9c6d914c4b8d9ca == %016llx\n",
         (unsigned long long) crc64(0,(unsigned char*)"123456789",9));
     Return 0;
}
Perform redundant operations on strings 1 through 9.





The following is the principle of the implementation of random algorithms in Redis, which was initially thought to be called math. Rand () method, and later found out that I was really wrong. The reasons given by the author are:




/* Pseudo random number generation functions derived from the drand48()
  * function obtained from pysam source code.
  *
  * This functions are used in order to replace the default math.random()
  * Lua implementation with something having exactly the same behavior
  * across different systems (by default Lua uses libc's rand() that is not
  * required to implement a specific PRNG generating the same sequence
  * in different systems if seeded with the same integer).
  *
  * The original code appears to be under the public domain.
  * I modified it removing the non needed functions and all the
  * 1960-style C coding stuff...
  *
  * Random functions may exhibit different behaviors in different systems, and the author does not use the math.random that comes with the system.
  *, but based on the random algorithm of drand48(), rewriting the behavior of random functions, the author took out the unneeded method when rewriting the random code
  * ------------------------------------------------- ---------------------------

This means that the author has rewritten the random algorithm. Based on the algorithm implementation is the DRAND48 () algorithm. Because this algorithm uses a 48-bit number, this name is used. Srand48 and drand48 are UNIX library functions, and the function of drand48 is to produce random numbers evenly distributed between [0,1], using linear same congruential and 48-bit integer operations to generate pseudo-random sequence functions using the above algorithm to produce a 48-bit pseudo-random integer, It then takes the high 32 bits of this integer as a random number and then plans the 32-bit pseudo-random number to [0,1], initializes the drand48 () with the function srand48, initializes the high 32 bits of the 48-bit integer only, and its low 16-bit is set to a random value. This is a pseudo-random generator with better statistical characteristics. These 2 functions are the original C language implementation:



#ifndef DRAND48_H
#define DRAND48_H

#include <stdlib.h>

#define m 0x100000000LL
#define c 0xB16
#define a 0x5DEECE66DLL

static unsigned long long seed = 1;

double drand48(void)
{
	seed = (a * seed + c) & 0xFFFFFFFFFFFFLL;
	unsigned int x = seed >> 16;
    return 	((double)x / (double)m);
	
}

void srand48(unsigned int i)
{
    seed  = (((long long int)i) << 16) | rand();
}

#endif


 

Because the rand () function of the system is still used here, the Z author does not bring the system itself, so the implementation here is slightly different in Redis:



Int32_t redisLrand48() {
     Next();
     Return (((int32_t)x[2] << (N - 1)) + (x[1] >> 1));
}

/* Set the seed */
Void redisSrand48(int32_t seedval) {
     SEED(X0, LOW(seedval), HIGH(seedval));
}

Static void next(void) {
     Uint32_t p[2], q[2], r[2], carry0, carry1;

     MUL(a[0], x[0], p);
     ADDEQU(p[0], c, carry0);
     ADDEQU(p[1], carry0, carry1);
     MUL(a[0], x[1], q);
     ADDEQU(p[1], q[0], carry0);
     MUL(a[1], x[0], r);
     x[2] = LOW(carry0 + carry1 + CARRY(p[1], r[0]) + q[1] + r[1] +
             a[0] * x[2] + a[1] * x[1] + a[2] * x[0]);
     x[1] = LOW(p[1] + r[0]);
     x[0] = LOW(p[0]);
}
The implementation of the specific next, referring to the source code, a variety of 4 operations and operations.





Redis Source Code Analysis (23)---CRC cyclic redundancy algorithm and Rand random number algorithm


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.