前两次的帖子
http://topic.csdn.net/u/20091112/12/fbe4e708-2abf-4f11-aba5-10d76876c1fa.html?341093157
http://topic.csdn.net/u/20091112/14/27ad5a3a-9a31-4462-9865-6f81c15cba59.html?1036448807暂时的问题有所解决,但心里还是有些不安。
如果程序只是最初NEW了下RANDOM,那13位密码出现雷同的情况会很小很小,可以忽略不计 我已经测试近千个点 没有看到有雷同的。
但今天因为翻了个错误,发现如果在程序运行中NEW了一个RANDOM输入到数据库一个,这种情况下就很有可能出现密码雷同的可能。
所以我猜想,如果重新启动程序的时候 NEW了RANDOM,那么这重新NEW了下RANDOM,是不是说明很有可能和重启前的某个密码出现雷同的情况呢?我不打算让密码作为数据库的主键了,打算在数据库里面增加一个字段ID INT型的自增的,这样就算出现密码雷同也不会有大问题,大不了几十万个雷同一个两个的 无所谓了

解决方案 »

  1.   


    namespace scbmMatchSystem
    {
        /// <summary>
        /// 线程安全的Random
        /// </summary>
        public class ThreadSafeRandom
        {        private static Random random = new Random();        /// <summary>
            /// 获取[0,1)之间的double
            /// </summary>
            /// <returns></returns>
            public static double NextDouble()
            {            lock (random)
                {                return random.NextDouble();            }        }        /// <summary>
            /// 获取[min,max)之间的double
            /// </summary>
            /// <param name="min">最小取值</param>
            /// <param name="max">最大取值</param>
            /// <returns></returns>
            public static double NextDouble(double min,double max)
            {            lock (random)
                {                return random.NextDouble()*(max-min) + min;            }        }        /// <summary>
            /// 获取[0,int.MaxValue)之间的int
            /// </summary>
            /// <returns></returns>
            public static int Next(){            lock (random)
                {
                    return random.Next();            }
            }        /// <summary>
            /// 获取[0,max)之间的int
            /// </summary>
            /// <param name="max">最大取值</param>
            /// <returns></returns>
            public static int Next(int max)
            {            lock (random)
                {
                    return random.Next(max);            }
            }        public static void NextBytes(byte[] buffer)
            {            lock (random)
                {
                    random.NextBytes(buffer);
                }
            }        /// <summary>
            /// 获取[min,max)之间的int
            /// </summary>
            /// <param name="min">最小取值</param>
            /// <param name="max">最大取值</param>
            /// <returns></returns>
            public static int Next(int min,int max)
            {            lock (random)
                {                return random.Next(min,max);
                }
            }
        }
    }
    用这个试试看
    ThreadSafeRandom.Next
      

  2.   

    你在SQL中处理吧,SELECT ABS(CHECKSUM(NEWID()))
    八位不重复的随机数
      

  3.   

    楼主我那帖好像回了用NEWID()来弄的,全局唯一标识符
      

  4.   

    用random是有点不保险,从C起,做随机数好像就不推荐用这个,一般都是自己写的函数(类).
      

  5.   


    //帮你随机出100万个数字 可惜文本太大 发不上来...560DC50118228
    372BDC34998A5
    1449D72819722
    F567EE5F9ADBF
    D285E1731A434
    B3A3F8669B2B1
    90C1F39A1C90E
    71FF8A899C78B
    511D9DBD1DE00
    3E3B94D09D49D
    1F59AFC41E31A
    FC77A6FB9F997
    DD95B9EF1F06C
    BAB3B10290EE9
    9BD1483610566
    78CF4325913E3
    59ED5A5912A78
    390B6D4C920F5
    0629646013F72
    E7477F97935CF
    C465768B14C44
    A58309BE95AC1
    82A100D21515E
    63DF1BC196FDB
    40FD12F516650
    201B25E897C2D
    01393D1C08AAA
    EE57343388127
    CF74CF2709FBC
    AC92C65A89639
    8DB0D94E0ACB6
    6AAED07D8BB33
    4BCCEB910B188
    28EAE2848C805
    0808F5B80C682
    E9268CAF8DD1F
    B64487C30EB94
    97629EF68E211
    748091EA0F8EE
    55BEA9198F76B
    32DCA00D00DE0
    13FABB208047D
    F318B254012FA
    D036454B82977
    B1545C7F027CC
    9E72579283E49
    7F906E86034C6
    5C8E61B584343
    3DAC78A9059D8
    1ACA73DC85055
    FBE80AF006ED2
    DB061DE7864AF
    B824151B07324
    99422C0EB89A1
    666027223803E
    479E3E51B9EBB
    24BC314539530
    05D9C878BA38D
    E2F7C36C3BA0A
    C215DA83BB087
    A333EDB73CF1C
    8051E4AABC599
    614FFFDE3DC16
    4E6DF6CDBEA93
    2F8B89E13E168
    0CA98114BFFE5
    EDC798083F662
    CAE5933FB0CFF
    AA03AA5331B74
    8B21BD46B11F1
    685FB47A3284E
    497D4F69B26CB
    169B469D33D40
    F7B959B0B4BDD
    D4D750A43425A
    B5F56BDBB58D7
    951362CF356AC
    723175E2B6D29
    532F0D1637BA6
    304D0405B7223
    116B1F39288B8
    FE89162CA8735
    DFA7294029DB2
    BCC52077A940F
    9DE33B6B2A284
    7D01329EAB901
    5A3EC5B22B79E
    3B5CDCA1ACE1B
    187AD7D52C490
    F998EEC8AD36D
    C6B6E1FC2E9EA
    A7D4F913AE067
    84F2F0072FEFC
    64108B3AAF579
    450E822E203F6
    222C955DA1A73
    034AAC71210C8
    E068A764A2F45
    C186BE98225C2
    AEA4B18FA3C5F
    8FC248A324AD4
    6CE043D6A4151
    4C1E5ACA25F2E
    2D3C6DF9A55AB
    33FED299FBA2D
    AA0D3BA3E4D1F
    025B00C50D049
    7A6969EF37ABB
    D2B7B73150DE5
    4AC59C5B790D7
    A513E57D63B01
    1D2232868CE73
    75701BA8B50BD
    ED9E60F2DFBEF
    45AC4E14F8ED9
    BDFA973EE110B
    1408FC400A475
    8C56C56A34EA7
    E465128C5D191
    5CB37BD6464C3
    B4C140F860F0D
    2CEFAE1D8927F
    873DF727B24A9
    FF4BDC49DCF9B
    579A2593C52C5
    CFA872B5EE537
    27F65BDF08861
    9E04A0E131353
    F6528E0B5A59D
    6E60D72D448CF
    C68F3C776D339
    3EDD05989666B
    96EB52A2B0955
    0139BBC4D9387
    794780EEC26F1
    D195EE30EC923
    49A4375A15C6D
    A1F21C7C3E75F
    1800658658989
    702EB2A841CFB
    E87C9BF26A725
    408AE11794A17
    B8D8CE39BDD41
    10E71743A67B3
    8B357C65C0AFD
    E343458FE9D2F
    5B9192D112019
    B3BFFBFB3CB4B
    2BCDC11D25DB5
    821C2E274E0E7
    FA2A774968BD1
    52785C9291E03
    CA86A5B4BA14D
    22D4F2DEA4BBF
    9AE2DBE0CDEE9
    F531210AF61DB
    6D5F0E2C1F405
    C56D577639F77
    3DBBBC98221A1
    95C985A24B493
    0C17D2C475FDD
    64263BE99E20F
    DC74013387579
    34826E55A1FAB
    ACD0B77FCA295
    04FE9C81F35C7
    7F0CE5AB1D831
    D75B32CD06363
    4F6918172F5AD
    A7B761394989F
    1FC54E43723C9
    761397649B63B
    EE21FC8E85965
    464FC5D0AEC57
    BE9E12FAD7681
    16AC781CF19F3
    8EFA41261AC3D
    F908AE480376F
    5156F7922DA59
    C964DCB456C8B
    21B325DE7F7F5
    99C172E399A27
    F1EF580582D11
    683DA12FAB043
    C04B8E71D5A8D
    3899D79BFEDFF
    90A83CBDE7029
    08F605C701B1B
    630452E92AE45
    DB52B833530B7
    336081557DBE1
    AB8EEE7F66ED3
    03DD37808F11D
    7BEB1CAAA844F
    D23965CCD2EB9
    4A47B316FB1EB
    A2959838E44D5
    1AA3E1420EF07
    72F1CE6437271
    ED00178E504A3
    452E7CD07AFED
    BD7C45FA632DF
    158A931F8C509
    8DD8F821B687B
    E5E6C14BDF2A5
    5C352E6DF8597
    B44377B7E28C1
    2C915CD90B333
    84BFA5E33467D
    FCCDF3055E8AF
    571BD82F47399
    CF2A2171606CB
    27780E9A8A935
    9F8657BCB3C67
    F7D4BCC6DC751
    6FE285E8C6983
    C630D332EFCCD
    3E5F38540873F
    966D017E32A69
    0EBB6E805BD5B
    66C9B7AA44785
    D1179CCC6EAF7
    4925EA1197D21
    A174333BB0013
    1982185DDAB5D
    71D06167C3D8F
    E9FE4E89EC0F9
    400C97D316B2B
    B85AFCF53FE15
    1068CA1F58147
    88B7132142BB1
    E0C5784B6BEE3
    5B13416C9412D
    B321AEB6BD41F
    2B4FF7D8A7F49
    839DDCE2C01BB
    FBAC2A04E94E5
    53FA732E13FD7
    CA0858703C201
    2256A19A25573
    9A648EBC4FFBD
    F2B2D7C6682EF
    6AC13CEB915D9
    C2EF0A0DBB80B
    3D3D5357A4375
    954BB879CD5A7
    0D998183F7891
    65A7EEA5103C3
    DDF637CF3960D
    34041D112397F
    AC526A3B4C3A9
    0460B35D7569B
    7C8E98669F9C5
    D4DCE188B8C37
    4CEACED2A1761
    A73917F4CBA53
    1F477D1EF4C9D
    77954A201D7CF
    EFA3934A07A39
    47F1F86C20D6B
    BE1FC1B649055
    162E2ED873A87
    8E7C77FD9CDF1
    E68A5D0785023
    5ED8AA29AFB6D
    B6E6F373C8E5F
    2134D895F1089
    994321BF1BBFB
    F1910EC104E25
    69BF57EB2D117
    C1CDBD0D56441
    381B8A5770EB3
    9029D378991FD
    087838828242F
    608601A4ACF19
    D8D46ECED524B
    30E2B410FE4B5
    AB309D3A18FE7
    035EEA5C012D1
    7B6D33662A503
    D3BB18885484D
    4BC961D27D2BF
    A2174EF4665E9
    1A259419808DB
    7273FD23A9305
    EA81CA45D2677
    42D0136FFC8A1
    BAFE78B1E5393
    150C41DB0E6DD
    8D5AAEFD2890F
    E568F40751C79
    5DB6DD297A6AB
    B5C52A7364995
    2C1373948DCC7
    ...
      

  6.   


                long def = 0x8910321267453;//这个.种子
                int index = 1;
                string temp ;
                List<string> list = new List<string>();
                long l = DateTime.Now.Ticks / 10000;// 日期值只需要1次就可以            while (list.Count < 1000000)//生成100万个
                {
                    l = (DateTime.Now.Ticks / 10000 * (index++) * def) ^ def;
                    temp = l.ToString("X");
                    if (temp.Length > 12)
                    {
                        //可以每次判断是否存在于集合中 存在就不继续添加,但是这样效率特别慢 至少10分钟才能处理100万条
                        //temp = temp.Substring(temp.Length - 13, 13);
                        //if (list.Contains(temp))
                        list.Add(temp);
                    }
                }
      

  7.   

                long def = 0x8910321267453;//这个.种子
                int index = 1;
                string temp ;
                List<string> list = new List<string>();
                long l = DateTime.Now.Ticks / 10000;// 日期值只需要1次就可以            while (list.Count < 1000000)//生成100万个
                {
                    l = (DateTime.Now.Ticks / 10000 * (index++) * def) ^ def;
                    temp = l.ToString("X");
                    if (temp.Length > 12)
                    {
                        //可以每次判断是否存在于集合中 存在就不继续添加,但是这样效率特别慢 至少10分钟才能处理100万条
                        temp = temp.Substring(temp.Length - 13, 13);
                        //if (list.Contains(temp))
                        list.Add(temp);
                    }
                }
    上面的多注释了一行...
      

  8.   

    楼主,我真佩服你的结帖速度,别人都是问题解决了几天不去结帖,你是问题没有解决就结了几次。看在你精神可嘉,提供给你一个最佳方案,是否采用就随便你了。
    使用Guid产生随机数:
    Guid.NewGuid().ToString()
    你可以测试下,每次调用Guid.NewGuid().ToString()获取到的字符串肯定不会一样,即使你是程序重新打开,也不会一样。
      

  9.   


    晕菜了 谁说不重复的? 你让它给我随机出0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF个不重复的数字来...
      

  10.   

    这就好比文件指纹还原文件,两个MD5码相同的文件肯定是同一个文件,你如果一定要说MD5码也有数量上限,文件数超过MD5码的上限就会出错,那就是钻牛角尖了。
      

  11.   


    难道你就不看其他网站吗? 井底之蛙http://social.microsoft.com/Forums/ru-RU/systemsmanagementserverzhchs/thread/830be053-dd74-4ea8-9175-e941aa5ade38这里就有某人给重复了 你说郁闷不? 他难道玩电脑玩了几十年了?
      

  12.   

    MD5现在已经被研究出碰撞了,之前我在网上亲眼见过被精心构造碰撞的两个图片,显示不同的正常内容,但MD5是一样的。不过如果是普通的正常使用,是可以认为MD5不重复的。
      

  13.   

    我不知道那种情况吗?我是“井底之蛙”,那你就是“井底之虫”。你自己看看实际应用中,GUID的使用范围,如果不好用,别人也不会那么广泛的使用了。使用GUID可以说是随机数选择的最方便,最可靠的方案。至于要防止重复也可简单,由于HashTable类的KEY是不允许重复的,使用时添加到HashTable的对象中,如果报错就重新获取GUID。放入HashTable还有一个好处,就是检索速度会很快。
      

  14.   

    问题是我取的只是数字,而且是是13 位,不知道对生成的GUID取位是否可行?
      

  15.   

    问题是我取的只是数字,而且是是13 位,不知道对生成的GUID取位是否可行? 你的代码我调试了 中间的那个 - 算不算一位 
      

  16.   

    如果我想取出纯数字的随机13位 用GUID行得通么 ?
    希望能说下 谢谢了!!
      

  17.   

    你可以两个GUID相加,然后再读取13位吧
      

  18.   

    如果你格式化输出,这样:
    Guid.NewGuid().ToString("N")
    你将看不到 -另外还可以Guid.NewGuid().ToByteArray()获取16个字节长度的字节数组,具体就要看哪种方便了。
      

  19.   

    private long GenerateIntID()
            {
                byte[] buffer = Guid.NewGuid().ToByteArray();
                return BitConverter.ToInt64(buffer, 0);
            }
    也可在生成后查询,只要查询合理,效率还是很高的
      

  20.   

    给你包装成函数调用,应该很方便使用:        /// <summary>
            /// 产生13位随机数字,前面不足补零。
             /// </summary>
            /// <param name="nums">记录产生的随机数,同时可以快速检索</param>
            /// <returns></returns>
            public string numString(Hashtable nums)
            {
                byte[] bytes = Guid.NewGuid().ToByteArray();
                ulong div = (ulong)Math.Pow(10, 13);
                ulong r1 = BitConverter.ToUInt64(bytes, 0) % div;
                ulong r2 = BitConverter.ToUInt64(bytes, 8) % div;
                string result = ((r1 + r2) % div).ToString("0000000000000");
                try
                {
                    nums.Add(result, null);
                    return result;
                }
                catch
                {
                    return numString(nums);
                }
            }
      

  21.   

    程序我调通了,加入我想取15位随机数不足取零的话,那函数内第二行的第二个参数应该改成15对么?也就是—>ulong div = (ulong)Math.Pow(10, 1);
    然后函数内第五行多写两个0 对么>也就是—>
    string result = ((r1 + r2) % div).ToString("000000000000000");
      

  22.   

    你想说ulong div = (ulong)Math.Pow(10, 15)吧; 
    怎么打成ulong div = (ulong)Math.Pow(10, 1)了呢?大致就是那样的。
      

  23.   


    写错参数了 重新发下
    程序我调通了,假如我想取15位随机数不足取零的话,那函数内第二行的第二个参数应该改成15对么?也就是—>ulong div = (ulong)Math.Pow(10, 15); 
    然后函数内第五行多写两个0 对么>也就是—> 
    string result = ((r1 + r2) % div).ToString("000000000000000");
      

  24.   

    想获得13位数字+字母混合的话,直接用Guid.NewGuid().ToString("N").Substring(0,13)获取就可以了。        /// <summary>
            /// 产生13位随机数字+字母。
             /// </summary>
            /// <param name="nums">记录产生的随机数,同时可以快速检索</param>
            /// <returns></returns>
            public string randomString(Hashtable nums)
            {
                string result = Guid.NewGuid().ToString("N").Substring(0,13);
                try
                {
                    nums.Add(result, null);
                    return result;
                }
                catch
                {
                    return randomString(nums);
                }
            }
      

  25.   

    谢谢!! 那就差一步了 就是纯字母 用GUID能做到纯字母随机么? 感觉不太可行  
      

  26.   

    纠正一下,由于Guid里出现的字母只能是a~f之间的这6个字母,所以如果想要全部字母的组合,就不能那样了。
      

  27.   

    恩相对少了些 不过感觉够用了  如果非要想做到26字母的话 感觉用伪随机+GUID可以 你觉得呢
      

  28.   

    的确,GUID获取的seed来创建随机数,相对随机性高一些,比如这样:
    int seed = Convert.ToInt32(Guid.NewGuid().ToByteArray());
    Random ran = new Random(seed);
      

  29.   

    好办法 关于伪随机Random  我一直有个东西有困惑 想请教下你
      

  30.   

    我先说一下我的理解,你看我说的对不对:
    我昨天了解到了“种子”这个概念,也就是每利用Random产生一个随机号,都是根据当前的系统时间为种子去做的一系列数学运算得到的伪随机号。既然种子是的源泉是系统时间,那时间是永远向前前进的,不可能时光倒流(打印人员真闲着没事去调整系统时间玩的情况除外),那就说明,种子是永远不同的。
    举个例子:
    比如: 今天5点30分28秒我用种子A去生成了随机数,那明天的5点30分28秒所用到的种子B,那么种子A就肯定不等于种子B,因为日期不同。就算日期也相同,年份又不同。所以种子就永远不会雷同。我理解的对么?
      

  31.   

    我用的是默认的Random 无参数的 使用系统时间做种子
      

  32.   

    你需要把时间转换为int类型后,就可以作为种子。        public void test()
            {
                Hashtable nums = new Hashtable();
                //int seed = BitConverter.ToInt32(Guid.NewGuid().ToByteArray(), 0);
                //Random ran = new Random(seed);
                Random ran1 = new Random((int)DateTime.Now.Ticks);//使用系统时间            List<char> chars = new List<char>();
                for (int i = (int)'a'; i <= (int)'z'; i++)
                {
                    chars.Add((char)i);
                }            MessageBox.Show(randomString(ran1, nums, chars));
            }        /// <summary>
            /// 产生13位随机字母。
             /// </summary>
            /// <param name="nums">记录产生的随机数,同时可以快速检索</param>
            /// <returns></returns>
            public string randomString(Random ran, Hashtable nums, List<char> list)
            {
                int length = list.Count;
                int index;
                StringBuilder sb = new StringBuilder(13);
                for (int i = 0; i < 13; i++)
                {
                    index = ran.Next(length - 1);
                    sb.Append(list[index]);
                }
                try
                {
                    nums.Add(sb.ToString(), null);
                    return sb.ToString();
                }
                catch
                {
                    return randomString(ran, nums, list);
                }
            }
      

  33.   

    up70楼
    用哈希表try插键值的办法很快很聪明
      

  34.   

    Random种子用GUID做 比系统用系统时间做更有随机性了 
    随机数 随机字母 随机数+字母 的种子都由GUID做种 就这么干了
    终于解决根本问题了 呵呵 谢谢qldsrx~.~ 
    结贴了