主頁 > 軟體工程 > 怎樣以最快的速度生成10000萬個隨機的不同16位數?

怎樣以最快的速度生成10000萬個隨機的不同16位數?

2020-09-23 09:51:15 軟體工程

我的方法是借助于資料庫的。資料庫表的欄位設定主鍵后插入重復資料會提示失敗,我就寫了個程式不斷地往資料庫里插入資料,遇到主鍵重復錯誤就忽略。代碼如下:
Private Sub Command1_Click()
    Dim s$
    Dim i As Single, sng1 As Single
    Dim j%
    On Error resume next'當資料庫主鍵欄位v_no有重復的時忽略錯誤
    For i = 1 To 10000000
        s = ""
        For j = 1 To 16'生成隨機16位數
            Randomize
            s = s & Mid("0123456789", Int(Rnd * 9) + 1, 1)
        Next
        Me.Caption = i & " " & s: DoEvents
        conn.Execute "INSERT INTO verify(v_no)  VALUES('" & s & "')"
    Next
End Sub


我用上述方法生成發現最多也就生成100萬個不同的資料。回圈一千萬次。 當重復執行后,也就是再回圈1000萬次,資料也就多了一兩萬而已。 重復的太多!! 怎樣最快速的生成呢?? 現在來看這個方法不可行,半個小時了才多幾百個新的隨機16位資料。

uj5u.com熱心網友回復:

先生成,再打亂

uj5u.com熱心網友回復:

使用前綴樹,每產生一個,就把對印的路徑標記出來。

uj5u.com熱心網友回復:

參考 2 樓 caozhy 的回復:
使用前綴樹,每產生一個,就把對印的路徑標記出來。

了解到些資訊。有人用的rsa,對資料加密和解密。

每次根本不用考慮重復。 直接對1~10萬 進行rsa加密成16位,都是一對一的。 而且可以解密。caozhy有了解這方面么?

uj5u.com熱心網友回復:

參考 3 樓 sysdzw 的回復:
Quote: 參考 2 樓 caozhy 的回復:

使用前綴樹,每產生一個,就把對印的路徑標記出來。

了解到些資訊。有人用的rsa,對資料加密和解密。

每次根本不用考慮重復。 直接對1~10萬 進行rsa加密成16位,都是一對一的。 而且可以解密。caozhy有了解這方面么?

不可能在不記憶和隨機同時滿足的情況下做到不重復。

uj5u.com熱心網友回復:

參考 4 樓 caozhy 的回復:
Quote: 參考 3 樓 sysdzw 的回復:

Quote: 參考 2 樓 caozhy 的回復:

使用前綴樹,每產生一個,就把對印的路徑標記出來。

了解到些資訊。有人用的rsa,對資料加密和解密。

每次根本不用考慮重復。 直接對1~10萬 進行rsa加密成16位,都是一對一的。 而且可以解密。caozhy有了解這方面么?

不可能在不記憶和隨機同時滿足的情況下做到不重復。
md5怎么說?

我的意思是人為記錄了起始和結尾有序的10萬個數了,用rsa加密后變成了16位寸數字無序的“密碼”,加密程序可逆。

找到個資源,可以研究下。
http://download.csdn.net/detail/xxlcb/2880873

uj5u.com熱心網友回復:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new GenDec16();
            foreach (var item in obj)
            {
                Console.WriteLine(item);
            }
        }
    }

    class GenDec16 : IEnumerator, IEnumerator<string>, IEnumerable<string>
    {
        class Tree
        {
            public Tree(int Length)
            {
                node = new Node(0, Length);
            }
            Node node;

            public string GenNewValue() { return node.GenNewValue(); }

            public bool HasNewValue
            {
                get
                {
                    return node.HasNewValue;
                }
            }
        }

        class Node
        {
            static Random rnd = new Random();

            public Node(int id, int level)
            {
                ID = id;
                Level = level;
                HasNewValue = true;
                if (level > 0) ChildNodes = new List<Node>();
            }

            public override string ToString()
            {
                return string.Format("{0}: childs={1}, hasnew={2}.", 
                    ID, 
                    string.Join(",", ChildNodes.Select(x => x.ID).OrderBy(x => x)), 
                    HasNewValue);
            }

            public int ID { get; set; }
            public bool HasNewValue { get; set; }
            public int Level { get; set; }
            List<Node> ChildNodes { get; set; }

            public string GenNewValue()
            {
                string result = "-";
                if (Level == 0)
                {
                    result = "";
                    HasNewValue = false;
                }
                else
                {
                    do
                    {
                        int n = Node.rnd.Next(0, 10);
                        var node = ChildNodes.SingleOrDefault(x => x.ID == n);
                        if (node == null)
                        {
                            node = new Node(n, Level - 1);
                            ChildNodes.Add(node);
                        }
                        if (!node.HasNewValue) continue;
                        result = n.ToString() + node.GenNewValue();
                    } while (result == "-");
                    HasNewValue = ChildNodes.Count != 10 || ChildNodes.Any(x => x.HasNewValue);
                }
                return result;
            }
        }

        Tree tree;

        public GenDec16()
        {
            (this as IEnumerator).Reset();
        }

        object IEnumerator.Current
        {
            get { return tree.GenNewValue(); }
        }

        bool IEnumerator.MoveNext()
        {
            return tree.HasNewValue;
        }

        void IEnumerator.Reset()
        {
            tree = new Tree(16); //16位
        }

        string IEnumerator<string>.Current { get { return tree.GenNewValue(); } }

        void IDisposable.Dispose()
        {
            
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }
}


貼一個我寫的代碼給你,跑1千萬,大約需要1分鐘。當然需要把輸出去掉。

uj5u.com熱心網友回復:

參考 5 樓 sysdzw 的回復:
Quote: 參考 4 樓 caozhy 的回復:

Quote: 參考 3 樓 sysdzw 的回復:

Quote: 參考 2 樓 caozhy 的回復:

使用前綴樹,每產生一個,就把對印的路徑標記出來。

了解到些資訊。有人用的rsa,對資料加密和解密。

每次根本不用考慮重復。 直接對1~10萬 進行rsa加密成16位,都是一對一的。 而且可以解密。caozhy有了解這方面么?

不可能在不記憶和隨機同時滿足的情況下做到不重復。
md5怎么說?

我的意思是人為記錄了起始和結尾有序的10萬個數了,用rsa加密后變成了16位寸數字無序的“密碼”,加密程序可逆。

找到個資源,可以研究下。
http://download.csdn.net/detail/xxlcb/2880873

反正不可能在不記憶和隨機同時滿足的情況下做到不重復。如果你增加生成的亂數的長度,可以降低重復的概率,最終當這個概率無限小的時候,可以視作不重復。

uj5u.com熱心網友回復:

洗牌演算法吧,先按順序生成,然后隨機打亂輸出

uj5u.com熱心網友回復:

參考 6 樓 caozhy 的回復:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new GenDec16();
            foreach (var item in obj)
            {
                Console.WriteLine(item);
            }
        }
    }

    class GenDec16 : IEnumerator, IEnumerator<string>, IEnumerable<string>
    {
        class Tree
        {
            public Tree(int Length)
            {
                node = new Node(0, Length);
            }
            Node node;

            public string GenNewValue() { return node.GenNewValue(); }

            public bool HasNewValue
            {
                get
                {
                    return node.HasNewValue;
                }
            }
        }

        class Node
        {
            static Random rnd = new Random();

            public Node(int id, int level)
            {
                ID = id;
                Level = level;
                HasNewValue = true;
                if (level > 0) ChildNodes = new List<Node>();
            }

            public override string ToString()
            {
                return string.Format("{0}: childs={1}, hasnew={2}.", 
                    ID, 
                    string.Join(",", ChildNodes.Select(x => x.ID).OrderBy(x => x)), 
                    HasNewValue);
            }

            public int ID { get; set; }
            public bool HasNewValue { get; set; }
            public int Level { get; set; }
            List<Node> ChildNodes { get; set; }

            public string GenNewValue()
            {
                string result = "-";
                if (Level == 0)
                {
                    result = "";
                    HasNewValue = false;
                }
                else
                {
                    do
                    {
                        int n = Node.rnd.Next(0, 10);
                        var node = ChildNodes.SingleOrDefault(x => x.ID == n);
                        if (node == null)
                        {
                            node = new Node(n, Level - 1);
                            ChildNodes.Add(node);
                        }
                        if (!node.HasNewValue) continue;
                        result = n.ToString() + node.GenNewValue();
                    } while (result == "-");
                    HasNewValue = ChildNodes.Count != 10 || ChildNodes.Any(x => x.HasNewValue);
                }
                return result;
            }
        }

        Tree tree;

        public GenDec16()
        {
            (this as IEnumerator).Reset();
        }

        object IEnumerator.Current
        {
            get { return tree.GenNewValue(); }
        }

        bool IEnumerator.MoveNext()
        {
            return tree.HasNewValue;
        }

        void IEnumerator.Reset()
        {
            tree = new Tree(16); //16位
        }

        string IEnumerator<string>.Current { get { return tree.GenNewValue(); } }

        void IDisposable.Dispose()
        {
            
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }
}


貼一個我寫的代碼給你,跑1千萬,大約需要1分鐘。當然需要把輸出去掉。

順便說下,如果你使用一種機制將tree物件持久化的話,就可以做到中斷/繼續生成。

這個演算法的好處在于,你可以不一次性地產生全部資料(那樣要好久),也不需要很多記憶體,就可以像使用自來水那樣隨時使用。并且效率很高。

uj5u.com熱心網友回復:

我不知道你是不是接受這種演算法,我電腦記憶體不夠,沒完整跑。

Private Sub Command1_Click()
    Dim D(99999999) As String, I As Long, TempID As Long, Temp As String
    Randomize Timer
    
    For I = 0 To UBound(D)
        '前八位隨機生成,后八位順序產生,不管怎么說,肯定不重復
        D(I) = Format(10000000 * Rnd, "00000000") & Format(I, "00000000")
    Next
    
    '你覺得隨機性不夠的話,再做洗牌處理
    For I = 0 To 99
      TempID = (UBound(D) + 1) * Rnd
      Temp = D(TempID)
      D(TempID) = D(I)
      D(I) = Temp
    Next

End Sub

uj5u.com熱心網友回復:

這樣也好吧,至少接受起來比前邊的好一些。

Private Sub Command1_Click()
    Dim D(99999999) As String, I As Long, Temp As String, J As Long
    Randomize Timer
    
    For I = 0 To UBound(D)
        '前八位隨機生成,后八位順序產生,不管怎么說,肯定不重復
        Temp = Format(10000000 * Rnd, "00000000") & Format(I, "00000000")
        For J = 1 To 8
            D(I) = D(I) & Mid(Temp, J, 1) & Mid(Temp, J + 8, 1) '把序號穿插在里邊,只要序列號的位置固定
        Next
    Next
End Sub

uj5u.com熱心網友回復:

參考 11 樓 bakw 的回復:
這樣也好吧,至少接受起來比前邊的好一些。

Private Sub Command1_Click()
    Dim D(99999999) As String, I As Long, Temp As String, J As Long
    Randomize Timer
    
    For I = 0 To UBound(D)
        '前八位隨機生成,后八位順序產生,不管怎么說,肯定不重復
        Temp = Format(10000000 * Rnd, "00000000") & Format(I, "00000000")
        For J = 1 To 8
            D(I) = D(I) & Mid(Temp, J, 1) & Mid(Temp, J + 8, 1) '把序號穿插在里邊,只要序列號的位置固定
        Next
    Next
End Sub
不接受,看起來不夠無序,不過是個思路。謝謝。

uj5u.com熱心網友回復:

參考 9 樓 caozhy 的回復:
Quote: 參考 6 樓 caozhy 的回復:

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var obj = new GenDec16();
            foreach (var item in obj)
            {
                Console.WriteLine(item);
            }
        }
    }

    class GenDec16 : IEnumerator, IEnumerator<string>, IEnumerable<string>
    {
        class Tree
        {
            public Tree(int Length)
            {
                node = new Node(0, Length);
            }
            Node node;

            public string GenNewValue() { return node.GenNewValue(); }

            public bool HasNewValue
            {
                get
                {
                    return node.HasNewValue;
                }
            }
        }

        class Node
        {
            static Random rnd = new Random();

            public Node(int id, int level)
            {
                ID = id;
                Level = level;
                HasNewValue = true;
                if (level > 0) ChildNodes = new List<Node>();
            }

            public override string ToString()
            {
                return string.Format("{0}: childs={1}, hasnew={2}.", 
                    ID, 
                    string.Join(",", ChildNodes.Select(x => x.ID).OrderBy(x => x)), 
                    HasNewValue);
            }

            public int ID { get; set; }
            public bool HasNewValue { get; set; }
            public int Level { get; set; }
            List<Node> ChildNodes { get; set; }

            public string GenNewValue()
            {
                string result = "-";
                if (Level == 0)
                {
                    result = "";
                    HasNewValue = false;
                }
                else
                {
                    do
                    {
                        int n = Node.rnd.Next(0, 10);
                        var node = ChildNodes.SingleOrDefault(x => x.ID == n);
                        if (node == null)
                        {
                            node = new Node(n, Level - 1);
                            ChildNodes.Add(node);
                        }
                        if (!node.HasNewValue) continue;
                        result = n.ToString() + node.GenNewValue();
                    } while (result == "-");
                    HasNewValue = ChildNodes.Count != 10 || ChildNodes.Any(x => x.HasNewValue);
                }
                return result;
            }
        }

        Tree tree;

        public GenDec16()
        {
            (this as IEnumerator).Reset();
        }

        object IEnumerator.Current
        {
            get { return tree.GenNewValue(); }
        }

        bool IEnumerator.MoveNext()
        {
            return tree.HasNewValue;
        }

        void IEnumerator.Reset()
        {
            tree = new Tree(16); //16位
        }

        string IEnumerator<string>.Current { get { return tree.GenNewValue(); } }

        void IDisposable.Dispose()
        {
            
        }

        IEnumerator<string> IEnumerable<string>.GetEnumerator()
        {
            return this;
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return this;
        }
    }
}


貼一個我寫的代碼給你,跑1千萬,大約需要1分鐘。當然需要把輸出去掉。

順便說下,如果你使用一種機制將tree物件持久化的話,就可以做到中斷/繼續生成。

這個演算法的好處在于,你可以不一次性地產生全部資料(那樣要好久),也不需要很多記憶體,就可以像使用自來水那樣隨時使用。并且效率很高。
代碼沒完全看懂。。但是我覺得靠亂數去處理這個問題 方向明顯偏了。 因為還有個致命的問題就是海量資料的時候資料庫查詢是個很大的問題。

新架構打算這樣。

批次表:

id  起始      結束    使用日期    備注   批次資訊描述  產品類別
1   1        100000   2013-1-5   10萬個資料
2   100001   300000   2013-5-13   30w個
3   300001   420000   2013-8-15   12萬個資料



--每次生成的時候我都用myras逐個加密成16位數的純數字(這個可以做到一對一),秘鑰只有我自己知道。
--當需要查詢一個某個資料的資訊時我只要用秘鑰解密,看介于那條記錄。查詢會很快。
select * form 批次表 where xx >=起始 and xx<=結束

uj5u.com熱心網友回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。

uj5u.com熱心網友回復:

還可以加時間截的辦法來生成隨時不重復的序列號,也一樣,要突破自己一個心理限制,而且這樣子的話生成的速度會有限制。

uj5u.com熱心網友回復:

參考 14 樓 bakw 的回復:
呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

uj5u.com熱心網友回復:

沒有,你可以試下,產生1千萬個資料使用大約1100萬個Node,每個十幾個位元組,可以在100MB數量級上搞定。
至于查找某個數字是否已經存在,更是瞬間完成。因為只要遍歷16個節點就可以了。

uj5u.com熱心網友回復:

反正我可以負責地告訴你,無論你加密解密,都回避不了這樣一個事實,如果不記錄所有已經產生的資料,無法做到絕對意義上的不重復。我用的演算法,只是將存盤和檢索已有資料做了優化而已。前綴樹避免了遍歷整個串列就可以查詢出一條數字是否已經存在。

uj5u.com熱心網友回復:

參考 17 樓 caozhy 的回復:
沒有,你可以試下,產生1千萬個資料使用大約1100萬個Node,每個十幾個位元組,可以在100MB數量級上搞定。
至于查找某個數字是否已經存在,更是瞬間完成。因為只要遍歷16個節點就可以了。
我只是個會vb的小白。 那代碼沒完全看懂。只知道資料結構里樹查找遍歷是很快。 有時間再研究研究了。 最終資料量可能是幾億級的,access還有空間大小估計都是個問題。所以沒有其他路子了。 我先看看myras(數字,秘鑰)怎么實作,目標是16位純數字。

uj5u.com熱心網友回復:

參考 16 樓 sysdzw 的回復:
Quote: 參考 14 樓 bakw 的回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

我不說誰知道,如果我不告訴你演算法,我說我提供給你一千萬個隨機號,那你覺得呢?覺得可行的話我幫你生成序列號,你拿著用,別管我怎么算出來,保證不重復。

uj5u.com熱心網友回復:

參考 18 樓 caozhy 的回復:
反正我可以負責地告訴你,無論你加密解密,都回避不了這樣一個事實,如果不記錄所有已經產生的資料,無法做到絕對意義上的不重復。我用的演算法,只是將存盤和檢索已有資料做了優化而已。前綴樹避免了遍歷整個串列就可以查詢出一條數字是否已經存在。
記錄了已經存在的資料了。 只是記錄的明文。明文是有序使用的,我人為的可以保證它不重復。 那表格看起來有點像磁盤磁區表。。

uj5u.com熱心網友回復:

參考 20 樓 bakw 的回復:
Quote: 參考 16 樓 sysdzw 的回復:

Quote: 參考 14 樓 bakw 的回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

我不說誰知道,如果我不告訴你演算法,我說我提供給你一千萬個隨機號,那你覺得呢?覺得可行的話我幫你生成序列號,你拿著用,別管我怎么算出來,保證不重復。
我以前想過,空出前三位表示作為代號。但是某個批次出來的產品,前面都一樣的編號是不允許的。所以廢棄了。 我本來是打算把這前三位代號分散到不連續的位,但是還是能看出來。 這方案我考慮過很深了。

uj5u.com熱心網友回復:

放在sqlserver區一個帖子。
http://bbs.csdn.net/topics/390548590

本打算用sqlserver生成海量資料慢慢用的。大牛確實多。

uj5u.com熱心網友回復:

你可以用代換法啊,把 1和9代換,3和6代換,這樣怎么還會看得出來?

uj5u.com熱心網友回復:

哎,睡覺了,主要還是心理這關過不去。N年前我就出過這種主意,都沒人信。見光死演算法吧。

uj5u.com熱心網友回復:

參考 24 樓 bakw 的回復:
你可以用代換法啊,把 1和9代換,3和6代換,這樣怎么還會看得出來?
再想想。  對調后可能還是一樣。 對調后可能和另外一個數字重復了。 不說了 隨機的方案反正已經否決了。 老大也沒多少空間讓我用。100萬就占用空間200M了。 access資料量達到500萬好像就極不穩定了,select一下都要有延遲。 

uj5u.com熱心網友回復:

參考 19 樓 sysdzw 的回復:
Quote: 參考 17 樓 caozhy 的回復:

沒有,你可以試下,產生1千萬個資料使用大約1100萬個Node,每個十幾個位元組,可以在100MB數量級上搞定。
至于查找某個數字是否已經存在,更是瞬間完成。因為只要遍歷16個節點就可以了。
我只是個會vb的小白。 那代碼沒完全看懂。只知道資料結構里樹查找遍歷是很快。 有時間再研究研究了。 最終資料量可能是幾億級的,access還有空間大小估計都是個問題。所以沒有其他路子了。 我先看看myras(數字,秘鑰)怎么實作,目標是16位純數字。



myras(數字,秘鑰)
我不管myras的實作,但是如果你的數字大于16位,函式的輸出是16位,則這個函式的輸出必然有重復。

uj5u.com熱心網友回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。

uj5u.com熱心網友回復:

我最初的想法也是用8+8或5+6+5的方式來串接,1000W條資料,重復的可能性非常小。
我看了下8+8的串接結果,感覺已經“很隨機”了。

你主貼中,Randomize 在最內層進行呼叫,并且字串操作量非常大,速度當然會很慢。
Randomize在回圈最內層呼叫也對“隨機性”基本沒什么增強作用。
并且,“Randomize + Rnd * 9”也會造成重復率極高。

uj5u.com熱心網友回復:

參考 29 樓 Chen8013 的回復:
我最初的想法也是用8+8或5+6+5的方式來串接,1000W條資料,重復的可能性非常小。
我看了下8+8的串接結果,感覺已經“很隨機”了。

你主貼中,Randomize 在最內層進行呼叫,并且字串操作量非常大,速度當然會很慢。
Randomize在回圈最內層呼叫也對“隨機性”基本沒什么增強作用。
并且,“Randomize + Rnd * 9”也會造成重復率極高。
之前一直在外層的。后來發現一直不產生新資料就挪進去了。 拼接的程序中不知道你怎么打亂的。資料量很大。 或許是什么隨機拼接大法?

uj5u.com熱心網友回復:

參考 28 樓 sysdzw 的回復:
傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。

uj5u.com熱心網友回復:

線性同余: http://bbs.csdn.net/topics/190019980

uj5u.com熱心網友回復:

Private Sub Command1_Click()
   Const TEXTBUFF As String = "0000000000000000"
   Const ITEMSIZE As Long = 10000000
   Const MULTIPLE As Long = 99999999   '用“8+8”
      Dim strTextOut(ITEMSIZE - 1) As String
      Dim strTemp$, i&
      
   Randomize
   For i = 0 To TEXTBUFF - 1
      strTemp = TEXTBUFF
      Mid$(strTemp, 1) = Int(Rnd() * MULTIPLE)
      Mid$(strTemp, 9) = Int(Rnd() * MULTIPLE)
      strTextOut(i) = strTemp
   Next
End Sub

uj5u.com熱心網友回復:

預先生成資料,添加從表里直接獲取,洗掉歸還到表中,即可。
即用有序的,亂數表,表示無序的亂數。


uj5u.com熱心網友回復:

資料生成用洗牌演算法!
資料太小,可以組合以組成更大的亂數。
使用,歸還演算法,可以用靜態鏈表。

uj5u.com熱心網友回復:

都是高手來的

uj5u.com熱心網友回復:

參考 22 樓 sysdzw 的回復:
Quote: 參考 20 樓 bakw 的回復:

Quote: 參考 16 樓 sysdzw 的回復:

Quote: 參考 14 樓 bakw 的回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

我不說誰知道,如果我不告訴你演算法,我說我提供給你一千萬個隨機號,那你覺得呢?覺得可行的話我幫你生成序列號,你拿著用,別管我怎么算出來,保證不重復。
我以前想過,空出前三位表示作為代號。但是某個批次出來的產品,前面都一樣的編號是不允許的。所以廢棄了。 我本來是打算把這前三位代號分散到不連續的位,但是還是能看出來。 這方案我考慮過很深了。


我用10秒鐘給你生成1000萬不重復的16位串號,真不知道你們到底認為有什么技術難點。。。。

uj5u.com熱心網友回復:

檔案大小175.7MB

uj5u.com熱心網友回復:

參考 38 樓 benben2301 的回復:
檔案大小175.7MB


他肯定會說不夠隨機。。

uj5u.com熱心網友回復:


對亂數的定義不同。樓主所說的,是不重復的 16 位數。

但實際上,FIPS 標準對亂數的檢測要嚴格得多,對隨機串長的定義也是不固定的。也就是說,以樓主的方法得到的“亂數”檔案,未必能通過亂數檢測。通俗地說,他們要檢測你的亂數序列中各種串長的重復性和對稱性。檢測方法十分復雜,包括很多項檢測。

實際上 ANSI 在 X9.31 及其增補檔案中,已經定義過偽亂數的生成方法:

- 基于 SHA-1 的 G 函式生成法;
- 基于 DES 的 G 函式生成法;
- 基于 TDES 的生成法;
- 基于 AES 的生成法。

用這些規定方法,很容易得到可以通過檢測的亂數。

這些亂數生成方法是美國規定用于銀行生成 RSA 數字簽名用的密鑰對的。其嚴格的密鑰生成演算法規定,主要是為了對抗銀行卡持有人對付款交易的抵賴。

uj5u.com熱心網友回復:

參考 37 樓 benben2301 的回復:
Quote: 參考 22 樓 sysdzw 的回復:

Quote: 參考 20 樓 bakw 的回復:

Quote: 參考 16 樓 sysdzw 的回復:

Quote: 參考 14 樓 bakw 的回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

我不說誰知道,如果我不告訴你演算法,我說我提供給你一千萬個隨機號,那你覺得呢?覺得可行的話我幫你生成序列號,你拿著用,別管我怎么算出來,保證不重復。
我以前想過,空出前三位表示作為代號。但是某個批次出來的產品,前面都一樣的編號是不允許的。所以廢棄了。 我本來是打算把這前三位代號分散到不連續的位,但是還是能看出來。 這方案我考慮過很深了。


我用10秒鐘給你生成1000萬不重復的16位串號,真不知道你們到底認為有什么技術難點。。。。

看起來很隨機了。每個16位數用了幾次隨機函式?還是其他的什么系統函式? 10秒鐘就1000萬很強大了。

uj5u.com熱心網友回復:

參考 31 樓 caozhy 的回復:
Quote: 參考 28 樓 sysdzw 的回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。
版主,這個方法做下來的話,會發現1和2加密后會發現只有一兩位是有差異。這是不行的。

uj5u.com熱心網友回復:

參考 42 樓 sysdzw 的回復:
Quote: 參考 31 樓 caozhy 的回復:

Quote: 參考 28 樓 sysdzw 的回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。
版主,這個方法做下來的話,會發現1和2加密后會發現只有一兩位是有差異。這是不行的。


不會啊。因為產生的6位亂數不同,用來異或后面10位出來的也不同。

uj5u.com熱心網友回復:

參考 43 樓 caozhy 的回復:
Quote: 參考 42 樓 sysdzw 的回復:

Quote: 參考 31 樓 caozhy 的回復:

Quote: 參考 28 樓 sysdzw 的回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。
版主,這個方法做下來的話,會發現1和2加密后會發現只有一兩位是有差異。這是不行的。


不會啊。因為產生的6位亂數不同,用來異或后面10位出來的也不同。
哦,那這樣好像不可逆了啊?因為不知道原來參與異或的是什么數。

uj5u.com熱心網友回復:

參考 44 樓 sysdzw 的回復:
Quote: 參考 43 樓 caozhy 的回復:

Quote: 參考 42 樓 sysdzw 的回復:

Quote: 參考 31 樓 caozhy 的回復:

Quote: 參考 28 樓 sysdzw 的回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。
版主,這個方法做下來的話,會發現1和2加密后會發現只有一兩位是有差異。這是不行的。


不會啊。因為產生的6位亂數不同,用來異或后面10位出來的也不同。
哦,那這樣好像不可逆了啊?因為不知道原來參與異或的是什么數。


可逆啊,前六位或者后六位明文保存這個亂數。

uj5u.com熱心網友回復:

參考 45 樓 caozhy 的回復:
Quote: 參考 44 樓 sysdzw 的回復:

Quote: 參考 43 樓 caozhy 的回復:

Quote: 參考 42 樓 sysdzw 的回復:

Quote: 參考 31 樓 caozhy 的回復:

Quote: 參考 28 樓 sysdzw 的回復:

傳進去的資料和輸出的資料是有個關系的。

你說的對 理論上必然會重復。

我得考慮下看看多少位一下不會重復。 加密后肯定要被明文大。 應該存在著10位以下映射為16位 還是沒有問題的吧。 10位數的話是100億,這輩子應該夠用了。。


是的,要這么說,構造一個編碼很簡單。

隨便舉例:

10位整數和6位亂數做異或,結果是10位異或以后的整數和那6位亂數。
版主,這個方法做下來的話,會發現1和2加密后會發現只有一兩位是有差異。這是不行的。


不會啊。因為產生的6位亂數不同,用來異或后面10位出來的也不同。
哦,那這樣好像不可逆了啊?因為不知道原來參與異或的是什么數。


可逆啊,前六位或者后六位明文保存這個亂數。
這個思路不錯。我再變換變換。 MsgBox 9999999999 Xor 1 這個試了下發現溢位。發現到MsgBox 1999999999 Xor 1 不溢位了,不過也有20億個數字了,足夠了。

uj5u.com熱心網友回復:

如果直接按“序號 xor 亂數”+ 亂數 的格式來產生,樓主肯定覺得這個“不夠隨機”了。


我覺得可以這樣處理一下,效果好一些:“(序號 Xor 亂數)回圈移位”+ 亂數
回圈移位只對低31位進行,讓符號位保持為0(這樣始終保持為正數)。
移位數,用亂數的低4位的值來決定(回圈移0~15位)。

由于0~1000W的序號,只用到了低3位元組,最高位元組始終是0,可以人為的置入非0值參與移位。
比如 “序號 Or &H5C000000”進行回圈移位。

這樣處理后,顯得比較隨機,并且還能夠還原出“原始序號”。

uj5u.com熱心網友回復:

只是,不知道這樣處理后,會不會造成出現“資料重復”的現象。

uj5u.com熱心網友回復:

Dim i, sngRnd1, strJiami
Dim strPart1$, strPart2$, strPart3$, strPart4$, strTemp$
Const TEXTBUFF As String = "0000000000000000"
txtresult1.Text = ""
Randomize
For i = t1.Text To t2.Text
    strTemp = TEXTBUFF
    sngRnd1 = Int(Rnd * 99999)
    strPart3 = Format(sngRnd1, "00000")
    Mid(strTemp, 11) = strPart3 '存放亂數
    strPart2 = CStr((i Xor sngRnd1) Xor 888) '這里的888是隨便加入的一個key
    strPart4 = 10 - Len(strPart2) '前面需要用0補齊的位數
    Mid(strTemp, strPart4 + 1) = strPart2 '存放異或的結果
    Mid(strTemp, 16) = (Val(strPart4) + Left(strPart3, 1)) Mod 10 '存放無用的0的個數
    If strPart4 > 0 Then Mid(strTemp, 1) = Int(Rnd * (10 ^ strPart4 - 1)) '需要用0補齊的位數用亂數填充
    txtresult1.Text = txtresult1.Text & strTemp & vbCrLf
Next
我將caozhy版主給出的方法稍微改進了下。 16位數分成4部分處理:隨機補齊0+異或結果+亂數+0位數的個數,看起來還行,只是一些大數還是看起來有部分重合。



大數:



這樣的方法生成100萬個只要幾秒啊。如果能對大數的情況再改進點就好了。

uj5u.com熱心網友回復:

參考 49 樓 sysdzw 的回復:
Dim i, sngRnd1, strJiami
Dim strPart1$, strPart2$, strPart3$, strPart4$, strTemp$
Const TEXTBUFF As String = "0000000000000000"
txtresult1.Text = ""
Randomize
For i = t1.Text To t2.Text
    strTemp = TEXTBUFF
    sngRnd1 = Int(Rnd * 99999)
    strPart3 = Format(sngRnd1, "00000")
    Mid(strTemp, 11) = strPart3 '存放亂數
    strPart2 = CStr((i Xor sngRnd1) Xor 888) '這里的888是隨便加入的一個key
    strPart4 = 10 - Len(strPart2) '前面需要用0補齊的位數
    Mid(strTemp, strPart4 + 1) = strPart2 '存放異或的結果
    Mid(strTemp, 16) = (Val(strPart4) + Left(strPart3, 1)) Mod 10 '存放無用的0的個數
    If strPart4 > 0 Then Mid(strTemp, 1) = Int(Rnd * (10 ^ strPart4 - 1)) '需要用0補齊的位數用亂數填充
    txtresult1.Text = txtresult1.Text & strTemp & vbCrLf
Next
我將caozhy版主給出的方法稍微改進了下。 16位數分成4部分處理:隨機補齊0+異或結果+亂數+0位數的個數,看起來還行,只是一些大數還是看起來有部分重合。



大數:



這樣的方法生成100萬個只要幾秒啊。如果能對大數的情況再改進點就好了。
caozhy版主幫忙看看這個方法有沒有什么隱患呢,別加密了然后沒法解密那就出大問題了。 解密方法很簡單:
Private Function jiemi(ByVal str1$) As String
    Dim i%, j%, strTmp%, s1$, s2$, s3$, s4$
    s1 = (Val(Right(str1, 1)) + 10 - Mid(str1, 11, 1)) Mod 10
    jiemi = Mid(str1, s1 + 1, 10 - s1) Xor Mid(str1, 11, 5) Xor 888
End Function

uj5u.com熱心網友回復:

你的“大數部分”效果不好,自然就是你的演算法不合理造成的。

你的“密文”前面10個字符,是跟“序號”相關的。
而你的 Xor 操作,一個是亂數(最大值99999),另一個是常數888,
Xor 的結果,只會影響到序號的低9位(二進制位),9位二進制 &H1FFFF = 131071,
也就是序號超過這個值的時候,“高位”部分不會變化,
&H1FFFF 的10進制數共6位,但最高位為1,相當于它的“影響力”還不足 5.5位(10進制位)。

簡單地說,你的 Xor 操作對“密文”的第1到第4個字符,不會有影響;
  如果序號的“十萬位”大于2時,你的Xor操作對第6字符基本無影響。

所以你就看到“大數”序號時,前面幾個字符沒變化的問題。
當然,序號倍數少時填充了亂數除外。
還有就是 Xor 操作時把第9位(低到高,2進制位)從0變成1造成進位除外
(比如你的19999......進位成20000.......)

uj5u.com熱心網友回復:

上面輸錯了一個字,應該是“你的Xor操作對第6字符基本無影響。”

樓主怎么不考慮對 xor 的結果進行回圈移位呢?

uj5u.com熱心網友回復:

暈,復制下來,沒把那個6改成5,就提交了。

uj5u.com熱心網友回復:

CoCreateGuid
Creates a GUID, a unique 128-bit integer used for CLSIDs and interface identifiers.

HRESULT CoCreateGuid(
  GUID  *pguid  //Pointer to the GUID on return
);
 
Parameter
pguid 
[out] Pointer to the requested GUID on return. 
Return Value
S_OK 
The GUID was successfully created. 
Win32 errors are returned byUuidCreate but wrapped as an HRESULT.

Remarks
The CoCreateGuid function calls the RPC function UuidCreate, which creates a GUID, a globally unique 128-bit integer. Use the CoCreateGuid function when you need an absolutely unique number that you will use as a persistent identifier in a distributed environment.To a very high degree of certainty, this function returns a unique value – no other invocation, on the same or any other system (networked or not), should return the same value.

QuickInfo
  Windows NT: Use version 3.1 or later.
  Windows: Use Windows 95 or later.
  Windows CE: Unsupported.
  Header: Declared in objbase.h.
  Import Library: Included as a resource in ole32.dll.

See Also
UuidCreate 



 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int d[6];
int i,n,a,b,t;
int c,j;
void main() {
    srand(time(NULL));
    printf("shuffle 0..n-1 demo\n");
    for (n=1;n<=5;n++) {/* 測驗1~5個元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j為n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 測驗n*2*n!次 */
            for (i=0;i<n;i++) d[i]=i;/* 填寫0~n-1 */
            for (i=n;i>0;i--) {/* 打亂0~n-1 */
                a=i-1;b=rand()%i;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=0;i<n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
    printf("shuffle 1..n demo\n");
    for (n=1;n<=5;n++) {/* 測驗1~5個元素 */
        printf("_____n=%d_____\n",n);
        j=1;
        for (c=1;c<=n;c++) j=j*c;/* j為n! */
        j*=n*2;
        for (c=1;c<=j;c++) {/* 測驗n*2*n!次 */
            for (i=1;i<=n;i++) d[i]=i;/* 填寫1~n */
            for (i=n;i>1;i--) {/* 打亂1~n */
                a=i;b=rand()%i+1;
                if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}
            }
            printf("%04d:",c);
            for (i=1;i<=n;i++) printf("%d",d[i]);
            printf("\n");
        }
    }
}

uj5u.com熱心網友回復:

這個其實不難吧,還是好好一些最基本的東西吧,我來弄兩個函式吧,只需用到dictionary、回圈以及加數學加減乘除就可以了,什么復雜的加密啊,神馬都是浮云;結果如下截圖所示,1000萬條資料兩個函式分別為約11秒和17秒半,可以根據不同的應用選擇不同回傳值函式,之所以兩個函式的時間相差很大,沒別的,就是value的型別及賦值問題,為int型別且直接賦0的顯然要快多了;回傳值long[]的函式為了使用輸出是16位,故最高位不取0值(當然,取0值也是可以的,到實際應用時若是用字串表示的話到時前面補足就行了)
(重要一點說明,dictionary的容量與作業系統位數及記憶體有關的,我是32位的,4G記憶體,3000萬條是沒問題的,所需的時間成線性的正比關系(這說明了數量對dictionary的ContainsKey函式的遍歷基本影響不大),但到了4000萬條時,函式的ToArray()運行出現了記憶體溢位;但如果是64位的系統,內在足夠大的話,1億,10都是沒問題的),本人用的是I5 2代的CPU,測驗的環境是在VS2010,net4.0

代碼:
------------begin code-------------
long[] thd_Randm10MillionNum(out int maxCF)
        {
            Dictionary<long, int> dicNum = new Dictionary<long, int>(10000000);
            Random rnd = new Random(); int max = 0;
            int total = 0;
            while (total < 10000000)
            {
                int count = 0;
                while (true)
                {
                    int j1 = rnd.Next(0, 10); int j2 = rnd.Next(0, 10); int j3 = rnd.Next(0, 10);
                    int j4 = rnd.Next(0, 10); int j5 = rnd.Next(0, 10); int j6 = rnd.Next(0, 10);
                    int j7 = rnd.Next(0, 10); int j8 = rnd.Next(0, 10); int j9 = rnd.Next(0, 10);
                    int j10 = rnd.Next(0, 10); int j11 = rnd.Next(0, 10); int j12 = rnd.Next(0, 10);
                    int j13 = rnd.Next(0, 10); int j14 = rnd.Next(0, 10); int j15 = rnd.Next(0, 10);
                    int j16 = rnd.Next(1, 10);//最高位不設為0
                    long l = j16 * 1000000000000000 + j15 * 100000000000000 + j14 * 10000000000000 + j13 * 1000000000000 + j12 * 100000000000 + j11 * 10000000000 + j10 * 1000000000 + j9 * 100000000 + j8 * 10000000 + j7 * 1000000 + j6 * 100000 + j5 * 10000 + j4 * 1000 + j3 * 100 + j2 * 10 + j1;
                    if (!dicNum.ContainsKey(l))
                    {
                        dicNum.Add(l, 0);
                        break;
                    }
                    else { count++; if (count > max)max = count; }
                }
                total++;
            }
            maxCF = max;
            return dicNum.Keys.ToArray();
        }
string[] thd_Randm10MillionStr(out int maxCF)
        {
            Dictionary<long, string> dicNum = new Dictionary<long, string>(10000000);
            Random rnd = new Random(); int max = 0;
            int total = 0;
            while (total < 10000000)
            {
                int count = 0;
                while (true)
                {
                    int j1 = rnd.Next(0, 10); int j2 = rnd.Next(0, 10); int j3 = rnd.Next(0, 10);
                    int j4 = rnd.Next(0, 10); int j5 = rnd.Next(0, 10); int j6 = rnd.Next(0, 10);
                    int j7 = rnd.Next(0, 10); int j8 = rnd.Next(0, 10); int j9 = rnd.Next(0, 10);
                    int j10 = rnd.Next(0, 10); int j11 = rnd.Next(0, 10); int j12 = rnd.Next(0, 10);
                    int j13 = rnd.Next(0, 10); int j14 = rnd.Next(0, 10); int j15 = rnd.Next(0, 10);
                    int j16 = rnd.Next(0, 10);
                    long l = j16 * 1000000000000000 + j15 * 100000000000000 + j14 * 10000000000000 + j13 * 1000000000000 + j12 * 100000000000 + j11 * 10000000000 + j10 * 1000000000 + j9 * 100000000 + j8 * 10000000 + j7 * 1000000 + j6 * 100000 + j5 * 10000 + j4 * 1000 + j3 * 100 + j2 * 10 + j1;
                    if (!dicNum.ContainsKey(l))
                    {
                        dicNum.Add(l, l.ToString("D16"));
                        break;
                    }
                    else { count++; if (count > max)max = count; }
                }
                total++;
            }
            maxCF = max;
            return dicNum.Values.ToArray();
        }
void thd_16Bits()
        {
            int count1, count4;
            DateTime dt1 = DateTime.Now;
            long[] Ls1 = thd_Randm10MillionNum(out count1);
            DateTime dt2 = DateTime.Now;
            string[] Lstrs2 = thd_Randm10MillionStr(out count4);
            DateTime dt3 = DateTime.Now;
            double ts1 = dt2.Subtract(dt1).TotalMilliseconds;
            double ts2 = dt3.Subtract(dt2).TotalMilliseconds;
            string temp = "";
            temp += "thd_Randm10MillionNum花時:" + ts1 + ",長度:" + Ls1.Length + ",最多重復次數:" + count1;
            temp += Environment.NewLine + "thd_Rand10MillionStrMath花時:" + ts2 + ",長度:" + Lstrs2.Length + ",最多重復次數:" + count4;
            MessageBox.Show(temp);
        }
        private void button15_Click(object sender, EventArgs e)
        {
            Thread thd = new Thread(thd_16Bits);
            thd.Start();
        }

-------------end code----------------

uj5u.com熱心網友回復:

參考 41 樓 sysdzw 的回復:
Quote: 參考 37 樓 benben2301 的回復:

Quote: 參考 22 樓 sysdzw 的回復:

Quote: 參考 20 樓 bakw 的回復:

Quote: 參考 16 樓 sysdzw 的回復:

Quote: 參考 14 樓 bakw 的回復:

呵呵,其實這個只是個人心理障礙的問題,就像變魔術,沒揭開別人就覺得很神奇,揭開了就覺得沒什么,一千萬正好是八位數全覆寫其實這樣挺好的。
不是這個意思。因為這樣跟半個流水號差不多。要嚴格的隨機無序。

我不說誰知道,如果我不告訴你演算法,我說我提供給你一千萬個隨機號,那你覺得呢?覺得可行的話我幫你生成序列號,你拿著用,別管我怎么算出來,保證不重復。
我以前想過,空出前三位表示作為代號。但是某個批次出來的產品,前面都一樣的編號是不允許的。所以廢棄了。 我本來是打算把這前三位代號分散到不連續的位,但是還是能看出來。 這方案我考慮過很深了。


我用10秒鐘給你生成1000萬不重復的16位串號,真不知道你們到底認為有什么技術難點。。。。

看起來很隨機了。每個16位數用了幾次隨機函式?還是其他的什么系統函式? 10秒鐘就1000萬很強大了。


程式在另一個帖子里貼了,非常簡單。。。。每個16位數使用16次亂數。

uj5u.com熱心網友回復:

生成1000W資料,在我的電腦上約14.5秒。

運行測驗過幾次,1000W資料,無重復。
樓主有興趣的話,可以試下2億或20億資料時有無重復。
Option Explicit

Private Sub Command1_Click()
   Const TEXTBUFF As String = "0000000000000000"
   Const ITEMSIZE As Long = 10000000
   Const VAL_BASE As Long = 12435
   Const VAL_VOLA As Long = 99999 - VAL_BASE
      Dim strTextOut(ITEMSIZE - 1) As String
      Dim strTemp$, i&, iRnd&
      Dim strDist$, p&
      
   Randomize
   For i = 0 To ITEMSIZE - 1
      strTemp = TEXTBUFF
      iRnd = VAL_BASE + Rnd() * VAL_VOLA
      Mid$(strTemp, 11) = iRnd
      iRnd = ULongCycL(i Xor iRnd, iRnd)
      strDist = iRnd
      p = 10 - Len(strDist)
      Mid$(strTemp, p + 1) = iRnd
      Mid$(strTemp, 16) = (p + Mid$(strTemp, 12, 1)) Mod 10
      If (p > 0) Then Mid$(strTemp, 1) = Left$(Int(Rnd() * VAL_VOLA), p)
      strTextOut(i) = strTemp
      'If (CLng(jiemi(strTemp)) <> i) Then MsgBox "解密出錯!", vbExclamation
   Next
End Sub

Private Function ULongCycL(ByVal iValue As Long, ByVal iBitsN As Long) As Long
   Dim iDivA&, iDivB&, iMASK&
   If (iValue = 0) Then ULongCycL = 0: Exit Function
   iBitsN = iBitsN Mod 31
   If (iBitsN = 0) Then
      ULongCycL = iValue:  Exit Function
   Else
      iDivA = 2 ^ iBitsN
      iDivB = 2 ^ (31 - iBitsN)
      iMASK = iDivB - 1
      ULongCycL = (iValue And iMASK) * iDivA _
                     Or (iValue And &H7FFFFFFF) \ iDivB
   End If
End Function

Private Function ULongCycR(ByVal iValue As Long, ByVal iBitsN As Long) As Long
   Dim iDivA&, iDivB&, iMASK&
   If (iValue = 0) Then ULongCycR = 0: Exit Function
   iBitsN = iBitsN Mod 31
   If (iBitsN = 0) Then
      ULongCycR = iValue:  Exit Function
   Else
      iDivA = 2 ^ (31 - iBitsN)
      iDivB = 2 ^ iBitsN
      iMASK = iDivB - 1
      ULongCycR = (iValue And iMASK) * iDivA _
                     Or (iValue And &H7FFFFFFF) \ iDivB
   End If
End Function

Private Function jiemi(strEnText As String) As String
' 對生成的16位序列號“還原”原始序號
      Dim p&, v&, strTemp$
   p = (10 + (Mid$(strEnText, 16) - Mid$(strEnText, 12, 1))) Mod 10
   v = Mid$(strEnText, 11, 5)
   jiemi = ULongCycR(CLng(Mid$(strEnText, p + 1, 10 - p)), v) Xor v
End Function

uj5u.com熱心網友回復:

用線性同余法可以直接生成1億個不重復的8位亂數,將前后兩個數用字串方式連接成16位,依然不重復。
Option Explicit

#Const OUTPUT_MODE = 1 '0:僅生成亂數; 1:合成16位編碼; 2:輸出編碼到csv檔案。'

Sub Main()
    Const a As Long = 21 '乘法系數'
    Const m As Long = 100000000 '模'
    Const c As Long = 65519 '增量'
    Dim r As Long '亂數'
    Dim rLast As Long '前個亂數'
    
    r = GetTickCount() '種子'
    
#If OUTPUT_MODE > 0 Then
    Dim sCode As String
    sCode = "00000000" & Format$(r, "00000000")
#End If
#If OUTPUT_MODE = 2 Then
    Dim hFile As Integer
    
    hFile = FreeFile()
    Open App.Path & "\Code-16.csv" For Output Access Write As #hFile
#End If

    Dim tc1 As Long
    Dim tc2 As Long
    Dim i As Long
    
    tc1 = GetTickCount()
    
#If OUTPUT_MODE = 2 Then
    For i = 0 To 1000000 '輸出檔案只測驗100萬個'
#ElseIf OUTPUT_MODE = 1 Then
    For i = 0 To 10000000 '合成只測驗1000萬個'
#Else
    For i = 0 To 100000000
#End If

        rLast = r
        r = (r * a + c) Mod m

#If OUTPUT_MODE > 0 Then
        Mid$(sCode, 1, 8) = Mid$(sCode, 9, 8)
        Mid$(sCode, 9, 8) = Format$(r, "00000000")
#End If
#If OUTPUT_MODE = 2 Then
        'Print #hFile, Format$(rLast, "00000000"); Format$(r, "00000000")
        Print #hFile, sCode
#End If

    Next
    
    tc2 = GetTickCount()

#If OUTPUT_MODE = 2 Then
    Close #hFile
#End If

    MsgBox (i - 1) & " 個用時 " & ((tc2 - tc1) / 1000) & " 秒。"
End Sub

Inter CPU 2.33GHz 的機器上,exe 執行結果
模式0: 1億個用時 1.063 秒。
模式1: 1千萬個用時 13.703 秒。
模式2: 1百萬個用時 2.984 秒。——這個和硬碟有關,意義不大。
輸出csv格式如下:
2837785996000558
9600055816077237
1607723737687496
3768749691502935
9150293521627154
2162715454235753
5423575339016332
3901633219408491
1940849107643830
0764383060585949
...


uj5u.com熱心網友回復:

同樣的方法,在 VB.Net 中合成編碼方便多了,而且速度也快。
dim rCode as long = CLng(rLast) * m + r
dim sCode as string = rCode.ToString("d16")

模式0: 1億個用時 1.094 秒。
模式1: 1千萬個用時 4.172 秒。

uj5u.com熱心網友回復:

留下罪證,秋后算賬

uj5u.com熱心網友回復:

挺有意思,占位學習!

uj5u.com熱心網友回復:

把16 位分為4*4。每四位隨機。
使用笛卡爾積得到所有的集合。

但這樣的應該不是最小密度的亂數。因為前面的固定了。這樣破解就會容易太多了。

uj5u.com熱心網友回復:

uj5u.com熱心網友回復:

學習了,都是高手

uj5u.com熱心網友回復:

learning

uj5u.com熱心網友回復:

參考 8 樓 bakw 的回復:
洗牌演算法吧,先按順序生成,然后隨機打亂輸出

這個策略最可靠,速度最快,不會出現重復選擇然后查詢的情況,以前進行過類似演算法的研究,這種思路最大的好處就是永遠不會隨機出重復資料,是否重復不需要判斷,這是其他演算法難以比擬的,需要判斷重復資料的演算法永遠的問題是產生大量資料后,最后幾個數字重復概率太高,也許最后一個數字永遠都隨機不出來了。
這個演算法可以理解為生成一個1000萬的順序串列,然后隨機(范圍0到1000萬-1)從串列中取數字,被取出的數字從串列中排除(為了排除方便,可能需要注意這個串列的資料結構模型,增加定位洗掉速度),下一次再取數字時,亂數范圍0到1000萬-2,也就是這個范圍每次減一,直到取完1000萬個數,這樣明面代碼回圈訪問串列的次數是2*1000萬,存盤空間最大1000萬個資料大小,效率是比較高的。
同時上面最后說明了是明面代碼回圈訪問陣列的次數,額外的訪問主要是串列資料結構的選擇有關,如果是陣列,定位速度不耗時間,但是洗掉元素要回圈移位,耗時比較厲害,選擇線性鏈表洗掉速度很快,就是定位耗時,不過僅僅是定位檢索,耗時相對快些,推薦使用線性鏈表,如果要求更高,估計要選用二叉樹等其他存盤方式,檢索和洗掉速度折中提高效率,二叉樹方式沒有具體嘗試過。

uj5u.com熱心網友回復:

我上面的演算法最適合的應用是隨機生成1000萬個數字序列,而且這些數字的范圍也是1到1000萬。
如果1000萬個16位數,因為1000萬才8位,所以還有及其大量的空余數字可以選擇,那么樓上幾位只要能保證不重復數字的演算法也都很強勁,學習下。

uj5u.com熱心網友回復:

加密的思路非常好,隨機選擇一個密碼,然后對1-10000k進行加密,得到的結果1.一定都是不同的(加密演算法的正確性);2.在不知道密碼的情況下,這些密文跟亂數沒有區別。(這是加密演算法的安全性),根本不需要記錄。斑竹知識面窄,不要動不動就說什么“不可能”,不懂不丟人,不要放棄治療。

uj5u.com熱心網友回復:

謝謝各位。隨機的方法大家給出了很多方法和思路,不少還直接給出了代碼,有c、c++、c#也有vb的。我最初用Chen8013的前八+后八隨機測驗,發現基本沒有重復的,這個是最簡單的辦法。其他各位也很不錯還沒來得及細細分析。

不過因為實際資料確實會很龐大,用任何一個資料庫都是個大問題,就是nosql之類的方法硬碟存盤也是個問題。 我現在只是將流水號加密,然后再解密核查屬于哪個批次。 這樣基本占用不了多少空間,任何一個一百來兆的虛擬主機都可以應付。 關于加密解密的問題我應該另外開個貼的。

uj5u.com熱心網友回復:

1億個亂數啊,那就拿10億以內,9的整倍數出來,然后按照提取的時間飛秒欄位排序就行了。

uj5u.com熱心網友回復:

參考 71 樓 yuwenge 的回復:
1億個亂數啊,那就拿10億以內,9的整倍數出來,然后按照提取的時間飛秒欄位排序就行了。

要獲取提取時間還是太占資源,干脆就按百位或者千位排序好了。

uj5u.com熱心網友回復:

不是有個獲取系統時間的嗎?
系統時間是要到毫秒的那種~
獲取到之后加再亂數然后再MD5下不就超簡單嗎?
這樣就要回圈10000萬次
就不會有相同的了~

uj5u.com熱心網友回復:

很簡單:前10位亂數,后6位時間戳遞增。

當年寫的卡號生成器就這樣,幾秒鐘就生成百萬條記錄了。

uj5u.com熱心網友回復:

會不會  出現重復的數字

uj5u.com熱心網友回復:

不知道效果怎么樣

uj5u.com熱心網友回復:

學習了,真的很不錯

uj5u.com熱心網友回復:

學習了,真的很不錯

uj5u.com熱心網友回復:

很好

uj5u.com熱心網友回復:

uj5u.com熱心網友回復:

參考 73 樓 a82344626 的回復:
不是有個獲取系統時間的嗎?
系統時間是要到毫秒的那種~
獲取到之后加再亂數然后再MD5下不就超簡單嗎?
這樣就要回圈10000萬次
就不會有相同的了~

一億條資料都做md5需要多少系統消耗?

uj5u.com熱心網友回復:

雖然不知道你們在說什么,但看起來很厲害的樣子。

uj5u.com熱心網友回復:

使用前綴樹,每產生一個,就把對印的路徑標記出來。 http://www.csxhgs.com/

uj5u.com熱心網友回復:

學習了,謝謝了

uj5u.com熱心網友回復:

分阿榮旗發軟文

轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/110935.html

標籤:VB基礎類

上一篇:關于v8::argument轉換成 c++型別的引數

下一篇:現在想一個 出入庫管理系統

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • Git本地庫既關聯GitHub又關聯Gitee

    創建代碼倉庫 使用gitee舉例(github和gitee差不多) 1.在gitee右上角點擊+,選擇新建倉庫 ? 2.選擇填寫倉庫資訊,然后進行創建 ? 3.服務端已經準備好了,本地開始作準備 (1)Git 全域設定 git config --global user.name "成鈺" git c ......

    uj5u.com 2020-09-10 05:04:14 more
  • CODING DevOps 代碼質量實戰系列第二課,相約周三

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。**《DevOps 代碼質量實戰(PHP 版)》**為 CODING DevOps 代碼質量實戰系列的第二課,同時也是本系列的 PHP ......

    uj5u.com 2020-09-10 05:07:43 more
  • 推薦Scrum書籍

    推薦Scrum書籍 直接上干貨,推薦書籍清單如下(推薦有順序的哦) Scrum指南 Scrum精髓 Scrum敏捷軟體開發 Scrum捷徑 硝煙中的Scrum和XP : 我們如何實施Scrum 敏捷軟體開發:Scrum實戰指南 Scrum要素 大規模Scrum:大規模敏捷組織的設計 用戶故事地圖 用 ......

    uj5u.com 2020-09-10 05:07:45 more
  • CODING DevOps 代碼質量實戰系列最后一課,周四發車

    隨著 ToB(企業服務)的興起和 ToC(消費互聯網)產品進入成熟期,線上故障帶來的損失越來越大,代碼質量越來越重要,而「質量內建」正是 DevOps 核心理念之一。 **《DevOps 代碼質量實戰(Java 版)》**為 CODING DevOps 代碼質量實戰系列的最后一課,同時也是本系列的 ......

    uj5u.com 2020-09-10 05:07:52 more
  • 敏捷軟體工程實踐書籍

    Scrum轉型想要做好,第一步先了解并真正落實Scrum,那么我推薦的Scrum書籍是要看懂并實踐的。第二步是團隊的工程實踐要做扎實。 下面推薦工程實踐書單: 重構:改善既有代碼的設計 決議極限編程 : 擁抱變化 代碼整潔代碼 程式員的職業素養 修改代碼的藝術 撰寫可讀代碼的藝術 測驗驅動開發 : ......

    uj5u.com 2020-09-10 05:07:55 more
  • Jenkins+svn+nginx實作windows環境自動部署vue前端專案

    前面文章介紹了Jenkins+svn+tomcat實作自動化部署,現在終于有空抽時間出來寫下Jenkins+svn+nginx實作自動部署vue前端專案。 jenkins的安裝和配置已經在前面文章進行介紹,下面介紹實作vue前端專案需要進行的哪些額外的步驟。 注意:在安裝jenkins和nginx的 ......

    uj5u.com 2020-09-10 05:08:49 more
  • CODING DevOps 微服務專案實戰系列第一課,明天等你

    CODING DevOps 微服務專案實戰系列第一課**《DevOps 微服務專案實戰:DevOps 初體驗》**將由 CODING DevOps 開發工程師 王寬老師 向大家介紹 DevOps 的基本理念,并探討為什么現代開發活動需要 DevOps,同時將以 eShopOnContainers 項 ......

    uj5u.com 2020-09-10 05:09:14 more
  • CODING DevOps 微服務專案實戰系列第二課來啦!

    近年來,工程專案的結構越來越復雜,需要接入合適的持續集成流水線形式,才能滿足更多變的需求,那么如何優雅地使用 CI 能力提升生產效率呢?CODING DevOps 微服務專案實戰系列第二課 《DevOps 微服務專案實戰:CI 進階用法》 將由 CODING DevOps 全堆疊工程師 何晨哲老師 向 ......

    uj5u.com 2020-09-10 05:09:33 more
  • CODING DevOps 微服務專案實戰系列最后一課,周四開講!

    隨著軟體工程越來越復雜化,如何在 Kubernetes 集群進行灰度發布成為了生產部署的”必修課“,而如何實作安全可控、自動化的灰度發布也成為了持續部署重點關注的問題。CODING DevOps 微服務專案實戰系列最后一課:**《DevOps 微服務專案實戰:基于 Nginx-ingress 的自動 ......

    uj5u.com 2020-09-10 05:10:00 more
  • CODING 儀表盤功能正式推出,實作作業資料可視化!

    CODING 儀表盤功能現已正式推出!該功能旨在用一張張統計卡片的形式,統計并展示使用 CODING 中所產生的資料。這意味著無需額外的設定,就可以收集歸納寶貴的作業資料并予之量化分析。這些海量的資料皆會以圖表或串列的方式躍然紙上,方便團隊成員隨時查看各專案的進度、狀態和指標,云端協作迎來真正意義上 ......

    uj5u.com 2020-09-10 05:11:01 more
最新发布
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:41:12 more
  • windows系統git使用ssh方式和gitee/github進行同步

    使用git來clone專案有兩種方式:HTTPS和SSH:
    HTTPS:不管是誰,拿到url隨便clone,但是在push的時候需要驗證用戶名和密碼;
    SSH:clone的專案你必須是擁有者或者管理員,而且需要在clone前添加SSH Key。SSH 在push的時候,是不需要輸入用戶名的,如果配置... ......

    uj5u.com 2023-04-19 08:35:34 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:05:44 more
  • 2023年農牧行業6大CRM系統、5大場景盤點

    在物聯網、大資料、云計算、人工智能、自動化技術等現代資訊技術蓬勃發展與逐步成熟的背景下,數字化正成為農牧行業供給側結構性變革與高質量發展的核心驅動因素。因此,改造和提升傳統農牧業、開拓創新現代智慧農牧業,加快推進農牧業的現代化、資訊化、數字化建設已成為農牧業發展的重要方向。 當下,企業數字化轉型已經 ......

    uj5u.com 2023-04-18 08:00:18 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:20:31 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:55 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:18:51 more
  • 談一談我對協同開發的一些認識

    如今各互聯網公司普通都使用敏捷開發,采用小步快跑的形式來進行專案開發。如果是小專案或者小需求,那一個開發可能就搞定了。但對于電商等復雜的系統,其功能多,結構復雜,一個人肯定是搞不定的,所以都是很多人來共同開發維護。以我曾經待過的商城團隊為例,光是后端開發就有七十多人。 為了更好地開發這類大型系統,往 ......

    uj5u.com 2023-04-17 08:18:00 more
  • 專案管理PRINCE2核心知識點整理

    PRINCE2,即 PRoject IN Controlled Environment(受控環境中的專案)是一種結構化的專案管理方法論,由英國政府內閣商務部(OGC)推出,是英國專案管理標準。
    PRINCE2 作為一種開放的方法論,是一套結構化的專案管理流程,描述了如何以一種邏輯性的、有組織的方法,... ......

    uj5u.com 2023-04-17 08:17:55 more
  • 計算機組成原理—存盤器

    計算機組成原理—硬體結構 二、存盤器 1.概述 存盤器是計算機系統中的記憶設備,用來存放程式和資料 1.1存盤器的層次結構 快取-主存層次主要解決CPU和主存速度不匹配的問題,速度接近快取 主存-輔存層次主要解決存盤系統的容量問題,容量接近與價位接近于主存 2.主存盤器 2.1概述 主存與CPU的聯 ......

    uj5u.com 2023-04-17 08:12:06 more