常用算法

一、LRU算法

原文:https://flychao88.iteye.com/blog/1977653

之前面试的时候,有被问到dbserver缓存2000人,那么如何去维护这2000个人,用一个怎样的算法来实现?今天看到这个算法,貌似可以应用到db缓存上,因为同理:最近登录过的玩家,那么在未来登录的概率就会比较高。相当于是热点数据。

二、sha1 c源码

/*
 * sha1.h
 *
 * Description:
 * This is the header file for code which implements the Secure
 * Hashing Algorithm 1 as defined in FIPS PUB 180-1 published
 * April 17, 1995.
 *
 * Many of the variable names in this code, especially the
 * single character names, were used because those were the names
 * used in the publication.
 *
 * Please read the file sha1.c for more information.
 *
 */
 
 #ifndef _SHA1_H_
 #define _SHA1_H_
 #include <stdint.h>
 /*
 * If you do not have the ISO standard stdint.h header file, then you
 * must typdef the following:
 * name meaning
 * uint32_t unsigned 32 bit integer
 * uint8_t unsigned 8 bit integer (i.e., unsigned char)
 * int_least16_t integer of >= 16 bits
 *
 */
 #ifndef _SHA_enum_
 #define _SHA_enum_
 enum
 {
     shaSuccess = 0,
     shaNull,         /* Null pointer parameter */
     shaInputTooLong, /* input data too long */
     shaStateError    /* called Input after Result */
 };
 #endif
 #define SHA1HashSize 20
 /*
 * This structure will hold context information for the SHA-1
 * hashing operation
 */
 typedef struct SHA1Context
 {
     uint32_t Intermediate_Hash[SHA1HashSize / 4]; /* Message Digest */
     uint32_t Length_Low; /* Message length in bits */
     uint32_t Length_High; /* Message length in bits */
     /* Index into message block array */
     int_least16_t Message_Block_Index;
     uint8_t Message_Block[64]; /* 512-bit message blocks */
     int Computed; /* Is the digest computed? */
     int Corrupted; /* Is the message digest corrupted? */
 } SHA1Context;
 
 
 /*
 * Function Prototypes
 */
 
 int SHA1Reset(SHA1Context *);
 int SHA1Input(SHA1Context *, const uint8_t *, unsigned int);
 int SHA1Result(SHA1Context *, uint8_t Message_Digest[SHA1HashSize]);
 
 #endif
/*
* sha1.c
*
* Description:
* This file implements the Secure Hashing Algorithm 1 as
* defined in FIPS PUB 180-1 published April 17, 1995.
*
* The SHA-1, produces a 160-bit message digest for a given
* data stream. It should take about 2**n steps to find a
* message with the same digest as a given message and
* 2**(n/2) to find any two messages with the same digest,
* when n is the digest size in bits. Therefore, this
* algorithm can serve as a means of providing a
* "fingerprint" for a message.
*
* Portability Issues:
* SHA-1 is defined in terms of 32-bit "words". This code
* uses <stdint.h> (included via "sha1.h" to define 32 and 8
* bit unsigned integer types. If your C compiler does not
* support 32 bit unsigned integers, this code is not
* appropriate.
*
* Caveats:
* SHA-1 is designed to work with messages less than 2^64 bits
* long. Although SHA-1 allows a message digest to be generated
* for messages of any number of bits less than 2^64, this
* implementation only works with messages with a length that is
* a multiple of the size of an 8-bit character.
*
*/
 
#include "SHA1.h"

#ifdef __cplusplus
extern "C"
{
#endif

    /*
    * Define the SHA1 circular left shift macro
    */
#define SHA1CircularShift(bits,word) \
    (((word) << (bits)) | ((word) >> (32-(bits))))
    /* Local Function Prototyptes */
    void SHA1PadMessage(SHA1Context *);
    void SHA1ProcessMessageBlock(SHA1Context *);
    /*
    * SHA1Reset
    *
    * Description:
    * This function will initialize the SHA1Context in preparation
    * for computing a new SHA1 message digest.
    *
    * Parameters:
    * context: [in/out]
    * The context to reset.
    *
    * Returns:
    * sha Error Code.
    *
    */
    int SHA1Reset(SHA1Context *context)//初始化状态
    {
        if (!context)
        {
            return shaNull;
        }
        context->Length_Low = 0;
        context->Length_High = 0;
        context->Message_Block_Index = 0;
        context->Intermediate_Hash[0] = 0x67452301;//取得的HASH结果(中间数据)
        context->Intermediate_Hash[1] = 0xEFCDAB89;
        context->Intermediate_Hash[2] = 0x98BADCFE;
        context->Intermediate_Hash[3] = 0x10325476;
        context->Intermediate_Hash[4] = 0xC3D2E1F0;
        context->Computed = 0;
        context->Corrupted = 0;
        return shaSuccess;
    }


    /*
    * SHA1Result
    *
    * Description:
    * This function will return the 160-bit message digest into the
    * Message_Digest array provided by the caller.
    * NOTE: The first octet of hash is stored in the 0th element,
    * the last octet of hash in the 19th element.
    *
    * Parameters:
    * context: [in/out]
    * The context to use to calculate the SHA-1 hash.
    * Message_Digest: [out]
    * Where the digest is returned.
    *
    * Returns:
    * sha Error Code.
    *
    */
    int SHA1Result(SHA1Context *context, uint8_t Message_Digest[SHA1HashSize])
    {
        int i;
        if (!context || !Message_Digest)
        {
            return shaNull;
        }
        if (context->Corrupted)
        {
            return context->Corrupted;
        }
        if (!context->Computed)
        {
            SHA1PadMessage(context);
            for (i = 0; i < 64; ++i)
            {
                /* message may be sensitive, clear it out */
                context->Message_Block[i] = 0;
            }
            context->Length_Low = 0; /* and clear length */
            context->Length_High = 0;
            context->Computed = 1;
        }
        for (i = 0; i < SHA1HashSize; ++i)
        {
            Message_Digest[i] = context->Intermediate_Hash[i >> 2]
                >> 8 * (3 - (i & 0x03));
        }
        return shaSuccess;
    }


    /*
    * SHA1Input
    *
    * Description:
    * This function accepts an array of octets as the next portion
    * of the message.
    *
    * Parameters:
    * context: [in/out]
    * The SHA context to update
    * message_array: [in]
    * An array of characters representing the next portion of
    * the message.
    * length: [in]
    * The length of the message in message_array
    *
    * Returns:
    * sha Error Code.
    *
    */

    int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
    {
        if (!length)
        {
            return shaSuccess;
        }
        if (!context || !message_array)
        {
            return shaNull;
        }
        if (context->Computed)
        {
            context->Corrupted = shaStateError;
            return shaStateError;
        }
        if (context->Corrupted)
        {
            return context->Corrupted;
        }
        while (length-- && !context->Corrupted)
        {
            context->Message_Block[context->Message_Block_Index++] =
                (*message_array & 0xFF);
            context->Length_Low += 8;
            if (context->Length_Low == 0)
            {
                context->Length_High++;
                if (context->Length_High == 0)
                {
                    /* Message is too long */
                    context->Corrupted = 1;
                }
            }
            if (context->Message_Block_Index == 64)
            {
                SHA1ProcessMessageBlock(context);
            }
            message_array++;
        }
        return shaSuccess;
    }

    /*
    * SHA1ProcessMessageBlock
    *
    * Description:
    * This function will process the next 512 bits of the message
    * stored in the Message_Block array.
    *
    * Parameters:
    * None.
    *
    * Returns:
    * Nothing.
    *
    * Comments:
    * Many of the variable names in this code, especially the
    * single character names, were used because those were the
    * names used in the publication.
    *
    */

    void SHA1ProcessMessageBlock(SHA1Context *context)
    {
        const uint32_t K[] = { /* Constants defined in SHA-1 */
            0x5A827999,
            0x6ED9EBA1,
            0x8F1BBCDC,
            0xCA62C1D6
        };
        int t; /* Loop counter */
        uint32_t temp; /* Temporary word value */
        uint32_t W[80]; /* Word sequence */
        uint32_t A, B, C, D, E; /* Word buffers */
        /*
        * Initialize the first 16 words in the array W
        */
        for (t = 0; t < 16; t++)
        {
            W[t] = context->Message_Block[t * 4] << 24;
            W[t] |= context->Message_Block[t * 4 + 1] << 16;
            W[t] |= context->Message_Block[t * 4 + 2] << 8;
            W[t] |= context->Message_Block[t * 4 + 3];
        }
        for (t = 16; t < 80; t++)
        {
            W[t] = SHA1CircularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
        }
        A = context->Intermediate_Hash[0];
        B = context->Intermediate_Hash[1];
        C = context->Intermediate_Hash[2];
        D = context->Intermediate_Hash[3];
        E = context->Intermediate_Hash[4];
        for (t = 0; t < 20; t++)
        {
            temp = SHA1CircularShift(5, A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
            E = D;
            D = C;
            C = SHA1CircularShift(30, B);
            B = A;
            A = temp;
        }
        for (t = 20; t < 40; t++)
        {
            temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1];
            E = D;
            D = C;
            C = SHA1CircularShift(30, B);
            B = A;
            A = temp;
        }
        for (t = 40; t < 60; t++)
        {
            temp = SHA1CircularShift(5, A) +
                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
            E = D;
            D = C;
            C = SHA1CircularShift(30, B);
            B = A;
            A = temp;
        }
        for (t = 60; t < 80; t++)
        {
            temp = SHA1CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3];
            E = D;
            D = C;
            C = SHA1CircularShift(30, B);
            B = A;
            A = temp;
        }
        context->Intermediate_Hash[0] += A;
        context->Intermediate_Hash[1] += B;
        context->Intermediate_Hash[2] += C;
        context->Intermediate_Hash[3] += D;
        context->Intermediate_Hash[4] += E;
        context->Message_Block_Index = 0;
    }


    /*
    * SHA1PadMessage
    *
    * Description:
    * According to the standard, the message must be padded to an even
    * 512 bits. The first padding bit must be a ’1’. The last 64
    * bits represent the length of the original message. All bits in
    * between should be 0. This function will pad the message
    * according to those rules by filling the Message_Block array
    * accordingly. It will also call the ProcessMessageBlock function
    * provided appropriately. When it returns, it can be assumed that
    * the message digest has been computed.
    *
    * Parameters:
    * context: [in/out]
    * The context to pad
    * ProcessMessageBlock: [in]
    * The appropriate SHA*ProcessMessageBlock function
    * Returns:
    * Nothing.
    *
    */

    void SHA1PadMessage(SHA1Context *context)
    {
        /*
        * Check to see if the current message block is too small to hold
        * the initial padding bits and length. If so, we will pad the
        * block, process it, and then continue padding into a second
        * block.
        */
        if (context->Message_Block_Index > 55)
        {
            context->Message_Block[context->Message_Block_Index++] = 0x80;
            while (context->Message_Block_Index < 64)
            {
                context->Message_Block[context->Message_Block_Index++] = 0;
            }
            SHA1ProcessMessageBlock(context);
            while (context->Message_Block_Index < 56)
            {
                context->Message_Block[context->Message_Block_Index++] = 0;
            }
        }
        else
        {
            context->Message_Block[context->Message_Block_Index++] = 0x80;
            while (context->Message_Block_Index < 56)
            {
                context->Message_Block[context->Message_Block_Index++] = 0;
            }
        }

        /*
        * Store the message length as the last 8 octets
        */
        context->Message_Block[56] = context->Length_High >> 24;
        context->Message_Block[57] = context->Length_High >> 16;
        context->Message_Block[58] = context->Length_High >> 8;
        context->Message_Block[59] = context->Length_High;
        context->Message_Block[60] = context->Length_Low >> 24;
        context->Message_Block[61] = context->Length_Low >> 16;
        context->Message_Block[62] = context->Length_Low >> 8;
        context->Message_Block[63] = context->Length_Low;
        SHA1ProcessMessageBlock(context);
    }


    #ifdef __cplusplus
    }
    #endif
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值