⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 md5.cpp

📁 经典的string 函数库学习资料
💻 CPP
字号:
/** * @file md5.cpp * @brief 字符串的包装,md5单向散列函数,crypt单向散列函数(md5算法) * @author 泥偶 * @since  2003-09-26 * @date   2003-11-03 */#define HAVE_MEMCPY#include "xstring.hpp"namespace x{    namespace    {        #include "md5.c"        /* magic sizes */        const int MD5_SIZE = 16;        static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */        "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";        void _crypt_to64(char* s, unsigned long v, int n)        {            while (--n >= 0) {                *s++ = itoa64[v&0x3f];                v >>= 6;            }        }        // 这个函数是 /usr/src/lib/libcrypt/crypt-md5.c 抄来的,做了一些修改        char* crypt_md5(const char *pw, const char *salt)        {            static char *magic = "$1$"; /*                             * This string is magic for                             * this algorithm.  Having                             * it this way, we can get                             * get better later on                             */            static char     passwd[120], *p;            static const char *sp, *ep;            unsigned char   final[MD5_SIZE];            int sl, pl, i;            md5_ctx ctx, ctx1;            unsigned long l;            /* Refine the Salt first */            sp = salt;            /* If it starts with the magic string, then skip that */            if (!strncmp(sp, magic, strlen(magic)))                sp += strlen(magic);            /* It stops at the first '$', max 8 chars */            for (ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++)            {                continue;            }            /* get the length of the true salt */            sl = ep - sp;            md5_init_ctx(&ctx);            /* The password first, since that is what is most unknown */            md5_process_bytes(pw, strlen(pw), &ctx);            /* Then our magic string */            md5_process_bytes(magic, strlen(magic), &ctx);            /* Then the raw salt */            md5_process_bytes(sp, sl, &ctx);            /* Then just as many characters of the MD5(pw, salt, pw) */            md5_init_ctx(&ctx1);            md5_process_bytes(pw, strlen(pw), &ctx1);            md5_process_bytes(sp, sl, &ctx1);            md5_process_bytes(pw, strlen(pw), &ctx1);            md5_finish_ctx(&ctx1, final);            for (pl = strlen(pw); pl > 0; pl -= MD5_SIZE)            {                md5_process_bytes(final, pl>MD5_SIZE ? MD5_SIZE : pl, &ctx);            }            /* Don't leave anything around in vm they could use. */            memset(final, 0, sizeof final);            /* Then something really weird... */            for (i = strlen(pw); i; i >>= 1)            {                if (i&1)                {                    md5_process_bytes(final, 1, &ctx);                }                else                {                    md5_process_bytes(pw, 1, &ctx);                }            }            /* Now make the output string */            strcpy(passwd, magic);            strncat(passwd, sp, sl);            strcat(passwd, "$");            md5_finish_ctx(&ctx, final);            /*             * and now, just to make sure things don't run too fast             * On a 60 Mhz Pentium this takes 34 msec, so you would             * need 30 seconds to build a 1000 entry dictionary...             */            for (i = 0; i < 1000; ++i)            {                md5_init_ctx(&ctx1);                if (i & 1)                {                    md5_process_bytes(pw, strlen(pw), &ctx1);                }                else                {                    md5_process_bytes(final, MD5_SIZE, &ctx1);                }                if (i % 3)                {                    md5_process_bytes(sp, sl, &ctx1);                }                if (i % 7)                {                    md5_process_bytes(pw, strlen(pw), &ctx1);                }                if (i & 1)                {                    md5_process_bytes(final, MD5_SIZE, &ctx1);                }                else                {                    md5_process_bytes(pw, strlen(pw), &ctx1);                }                md5_finish_ctx(&ctx1, final);            }            p = passwd + strlen(passwd);            l = (final[ 0]<<16) | (final[ 6]<<8) | final[12];            _crypt_to64(p, l, 4); p += 4;            l = (final[ 1]<<16) | (final[ 7]<<8) | final[13];            _crypt_to64(p, l, 4); p += 4;            l = (final[ 2]<<16) | (final[ 8]<<8) | final[14];            _crypt_to64(p, l, 4); p += 4;            l = (final[ 3]<<16) | (final[ 9]<<8) | final[15];            _crypt_to64(p, l, 4); p += 4;            l = (final[ 4]<<16) | (final[10]<<8) | final[ 5];            _crypt_to64(p, l, 4); p += 4;            l =                    final[11]                ;            _crypt_to64(p, l, 2); p += 2;            *p = '\0';            /* Don't leave anything around in vm they could use. */            memset(final, 0, sizeof final);            return passwd;        }    }   // namespace//----------------------------------------------------------------------------    /**    根据    <a href="http://www.faqs.org/rfcs/rfc1321">RSA Data Security, Inc.    MD5 Message-Digest Algorithm</a>计算字符串的MD5散列。    这个散列是一个32个字符的十六进制数字。    如果可选的raw_output被设置成true,那将会返回16个字符长度的原始二进制格式。    @code  * xstring str = "apple";  * if ("1f3870be274f6c49b3e31a0c6728957f" == str.md5())  * {  *     cout << "Would you like a green or red apple?";  * }    @endcode    raw_output参数是1.0.2test3版本新增的    @see crc32() sha1()     */    xstring xstring::md5(bool raw_output) const    {        char digest[16];        md5_buffer(this->data(), this->size(), digest);        xstring str(digest, sizeof(digest));        if (raw_output)        {            return str;        }        return str.bin2hex();    }    /**    @return 基于UNIX MD5的加密算法加密过的字符串。    CRYPT_MD5 - 基于MD5的加密算法。以@$1@$开始,附带12个字符的盐(salt)。    @see md5()     */    xstring xstring::crypt(const xstring& salt) const    {        return xstring(crypt_md5(this->c_str(), salt.c_str()));    }}   // namespace x

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -