如何用两个字符串生成一个唯一的数字

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用两个字符串生成一个唯一的数字相关的知识,希望对你有一定的参考价值。

参考技术A

    参考做法:将这两个字串合并,生成合并字串的MD5.

    MD5的作用:

MD5的作用是让大容量信息在用数字签名软件签署私人密钥前被"压缩"成一种保密的格式(就是把一个任意长度的字节串变换成一定长的十六进制数字串)。除了MD5以外,其中比较有名的还有sha-1、RIPEMD以及Haval等。

3.MD5算法具有以下特点:

3.1压缩性:任意长度的数据,算出的MD5值长度都是固定的。

3.2容易计算:从原数据计算出MD5值很容易。

3.3抗修改性:对原数据进行任何改动,哪怕只修改1个字节,所得到的MD5值都有很大区别。

3.4强抗碰撞:已知原数据和其MD5值,想找到一个具有相同MD5值的数据(即伪造数据)是非常困难的。

生成的MD5结果,本身就是十六进制数,可以再转换成相应的10进制数。下面代码是C++生成MD5:

#include<iostream>
#include<string>
using namespace std;
#define shift(x, n) (((x) << (n)) | ((x) >> (32-(n))))//右移的时候,高位一定要补零,而不是补充符号位
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))    
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
#define A 0x67452301
#define B 0xefcdab89
#define C 0x98badcfe
#define D 0x10325476
//strBaye的长度
unsigned int strlength;
//A,B,C,D的临时变量
unsigned int atemp;
unsigned int btemp;
unsigned int ctemp;
unsigned int dtemp;
//常量ti unsigned int(abs(sin(i+1))*(2pow32))
const unsigned int 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;
//向左位移数
const unsigned int s[]=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;
const char str16[]="0123456789abcdef";
void mainLoop(unsigned int M[])

    unsigned int f,g;
    unsigned int a=atemp;
    unsigned int b=btemp;
    unsigned int c=ctemp;
    unsigned int d=dtemp;
    for (unsigned int i = 0; i < 64; i++)
    
        if(i<16)
            f=F(b,c,d);
            g=i;
        else if (i<32)
        
            f=G(b,c,d);
            g=(5*i+1)%16;
        else if(i<48)
            f=H(b,c,d);
            g=(3*i+5)%16;
        else
            f=I(b,c,d);
            g=(7*i)%16;
        
        unsigned int tmp=d;
        d=c;
        c=b;
        b=b+shift((a+f+k[i]+M[g]),s[i]);
        a=tmp;
    
    atemp=a+atemp;
    btemp=b+btemp;
    ctemp=c+ctemp;
    dtemp=d+dtemp;

/*
*填充函数
*处理后应满足bits≡448(mod512),字节就是bytes≡56(mode64)
*填充方式为先加一个1,其它位补零
*最后加上64位的原来长度
*/
unsigned int* add(string str)

    unsigned int num=((str.length()+8)/64)+1;//以512位,64个字节为一组
    unsigned int *strByte=new unsigned int[num*16];    //64/4=16,所以有16个整数
    strlength=num*16;
    for (unsigned int i = 0; i < num*16; i++)
        strByte[i]=0;
    for (unsigned int i=0; i <str.length(); i++)
    
        strByte[i>>2]|=(str[i])<<((i%4)*8);//一个整数存储四个字节,i>>2表示i/4 一个unsigned int对应4个字节,保存4个字符信息
    
    strByte[str.length()>>2]|=0x80<<(((str.length()%4))*8);//尾部添加1 一个unsigned int保存4个字符信息,所以用128左移
    /*
    *添加原长度,长度指位的长度,所以要乘8,然后是小端序,所以放在倒数第二个,这里长度只用了32位
    */
    strByte[num*16-2]=str.length()*8;
    return strByte;

string changeHex(int a)

    int b;
    string str1;
    string str="";
    for(int i=0;i<4;i++)
    
        str1="";
        b=((a>>i*8)%(1<<8))&0xff;   //逆序处理每个字节
        for (int j = 0; j < 2; j++)
        
            str1.insert(0,1,str16[b%16]);
            b=b/16;
        
        str+=str1;
    
    return str;

string getMD5(string source)

    atemp=A;    //初始化
    btemp=B;
    ctemp=C;
    dtemp=D;
    unsigned int *strByte=add(source);
    for(unsigned int i=0;i<strlength/16;i++)
    
        unsigned int num[16];
        for(unsigned int j=0;j<16;j++)
            num[j]=strByte[i*16+j];
        mainLoop(num);
    
    return changeHex(atemp).append(changeHex(btemp)).append(changeHex(ctemp)).append(changeHex(dtemp));

int main()

    string ss,t;

    cin>>ss;  //输入串
    t=ss+"abc";//输入串加上“abc”合并
    cou<<t<<endl;//输出合并串
    string s=getMD5(t);//获取合并串md5
    cout<<s<<endl;//输出结果
    return 0;

如何为数据库中的一列生成唯一的字符串?

我试图用唯一的字符串填充数据库中的一列。我如何实现这个目标?

我目前的代码只是调用了同一个实例的 GetUniqueKey() 方法,所以它只是生成相同的密钥。这个方法只会运行一次。就像我说的,我试图为每一行生成一个唯一的键。这个 GetUniqueKey() 方法生成一个字母数字字符串。我如何在 Hash.GetUniqueKey() 以获得一个新的唯一键?

private readonly int KEY_SIZE = 5;

public void Fill() {
    connectionStringBuilder.InitialCatalog = "parts";
    connection.ConnectionString = CONSTANTS.connStringParts;

    string query = @"UPDATE parts SET [InternalID] = '" + Hash.GetUniqueKey(KEY_SIZE) + "'";
    SqlCommand command = new SqlCommand(query, connection);
    using(connection) {

        try {
            connection.Open();
            command.ExecuteNonQuery();
            connection.Close();
        }
        catch(Exception ex) {
            MessageBox.Show(Resource1.DatabaseConnectionError, Resource1.Error, MessageBoxButton.OK, MessageBoxImage.Error);
        }
    }
}
答案

你有没有考虑使用Guid?

https:/docs.microsoft.comtr-trdotnetapisystem.guid.newguid?view=netframework-4.8。

// Create and display the value of two GUIDs.
Guid g = Guid.NewGuid();
Console.WriteLine(g);
Console.WriteLine(Guid.NewGuid());

// This code example produces a result similar to the following:

// 0f8fad5b-d9cb-469f-a165-70867728950e
// 7c9e6679-7425-40de-944b-e07fc1f90ae7

以上是关于如何用两个字符串生成一个唯一的数字的主要内容,如果未能解决你的问题,请参考以下文章

如何用java生成有规律的字符串?

如何用相同长度的唯一数字替换特定长度的字符

如何用java随机生成一个字母

如何用EXCEL随机生成一定位数的字符串

如何用BAT判断文本中的字符串是不是为纯数字,即没有字母,并去执行两个相应的操作

如何用redis来生成唯一Id