2 million takes approximately 10 seconds to output the result to a TXT file.
- Sub GetPassword () ' by Kagawa
- Dim I&, J&, K&, L&, M&, N&, R&, S $, s1$, s2$, t$, C1&, C2&, Cnt&, tms#
- TMS = Timer
- m = ActiveCell
- If m = 0 Then M = 2 * 10 ^ 6
- n = 6
- s = "abc2def3hjk4lm5npq7rst8uvw9xyz" ' primitive characters deliberately break numbers evenly into letters
- S1 = "2345789" ' Only number
- S2 = "abcdefhjklmnpqrstuvwxyz" ' letters only
- L = Len (s)
- L1 = Len (S1)
- L2 = Len (s2)
- ReDim arr (1 to L) as Boolean records an array of numeric positions for later checking for numbers
- For i = 1 to L
- If IsNumeric (Mid (S, I, 1)) then arr (i) = True
- Next
- ReDim brr& (1 to n-1) ' password first 5-bit corresponding ordinal base value for future calls to save compute time
- For i = 1 to n-1
- K = k + L ^ (i-1)
- BRR (i) = l ^ (i-1)
- Next
- ReDim crr$ (1 to K * L) ' defines an array that records the corresponding ordinal of the first 5 characters for easy elimination of duplicates
- t = "VN" & String (N, "") ' generates whitespace characters that require length
- Open Activeworkbook.path & "\password.txt" for Output as #1 ' opening txt record file
- Randomize ' Random seed initialization to get different random sequences each time the macro runs
- For i = 1 to M ' generates a password of the specified number of =m
- Do
- C1 = 0:C2 = 0:k = 0 ' record initialization c1= with digit c2= first 5 digits with letter k=
- For j = 1 to N-1
- R = Int (RND * l) + 1 ' get random characters
- K = k + R * BRR (j) ' Calculate cumulative serial number
- If arr (r) Then C1 = 1 Else c2 = 1 ' checks if the record contains numbers or letters
- Mid (T, J + 2, 1) = Mid (S, r, 1) ' Replace the random character with the specified position
- Next
- If C1 + c2 = 2 Then ' if the values and characters contain
- R = Int (RND * l) + 1 ' then you can take any value
- Mid (T, J + 2, 1) = Mid (S, r, 1)
- Else
- If C1 = 0 Then ' If the number is not included
- R = Int (Rnd * L1) + 1 ' That last join number
- Mid (T, J + 2, 1) = Mid (S1, R, 1)
- Else ' If it does not contain letters
- R = Int (RND * L2) + 1 ' last join letter
- Mid (T, J + 2, 1) = Mid (S2, r, 1)
- End If
- End If
- If CRR (k) = "then" if the first 5-bit sequence number is not duplicate record is empty
- CRR (k) = T ' records this valid result for future check repetition
- Print #1, T ' record to TXT file
- Exit Do ' exits this calculation
- Else ' If the sequence number already has a record
- If InStr (CRR (k), T) = 0 Then further checks if it is the same if different is valid
- CRR (k) = CRR (k) & "," & T "records add new results for future check duplicates
- Print #1, T ' record to TXT file
- Exit Do ' exits this calculation
- Else
- CNT = cnt + 1 ' statistical repetition count
- End If
- End If
- Loop
- Next
- Close #1 ' closing TXT file
- ActiveCell.Offset (, 1) = Format (Timer-tms, "0.000")
- ActiveCell.Offset (, 2) = cnt
- ActiveCell.Offset (1). Activate
- MsgBox Format (Timer-tms, "0.000s") & CNT & "/" & M
- End Sub
The "Dictionary nesting Algorithm", which generates 2 million of non-repeating passwords, breaks through the obstacles that the dictionary method is bound to crash in a large number.
But the actual speed is still relatively slow, 3-5 times slower than my array to prevent repetition.
- Sub Test5 ()
- Dim d, I&, M&, S, t$, t1$, t2$, Cnt&, tms#
- TMS = Timer
- m = activecell:if m = 0 Then M = 2 * 10 ^ 6
- ' s = Split ("2 3 4 5 7 8 9 A B C D E F H J K L M N P Q R s T U V W X Y Z")
- s = Split ("A B C 2 D E F 3 H J K 4 L M 5 N P Q 7 R S T 8 U V W 9 X Y Z")
- Open Activeworkbook.path & "\password.txt" for Output as #1
- Set d = CreateObject ("Scripting.Dictionary")
- Randomize
- Do
- T1 = ""
- For i = 1 to 2
- T1 = T1 & S ((RND * 30))
- Next
- If not d.exists (t1) then Set d (T1) = CreateObject ("Scripting.Dictionary")
- ' Only the first 2 characters are added as keys to the dictionary, and each new key is set as a nested dictionary.
- Do
- T2 = ""
- For i = 1 to 4
- T2 = T2 & S ((RND * 30))
- Next
- If not D (T1). Exists (T2) Then ' after four bit in dictionary if not repeating
- t = "VN" & T1 & T2 ' pin it Out
- If t like "*[0-9]*" and then ' confirms that it contains a number
- If t like "vn*[a-z]*" then ' confirm with letters
- D (T1) (t2) = "" "The password is effectively added to the nested dictionary to exclude future duplicates
- Print #1, t ' output results to TXT file
- CNT = cnt + 1 ' Active statistics +1
- Exit do
- End If
- End If
- End If
- Loop
- Loop Until cnt = m ' reaches target number such as 2 million after exiting
- Close #1 ' closing TXT file
- ActiveCell.Offset (, 1) = Format (Timer-tms, "0.000")
- ActiveCell.Offset (1). Activate
- MsgBox Format (Timer-tms, "0.000s") & M
- ' The following is a count of the number of keywords in each nested dictionary.
- KRR = D.keys
- For i = 0 to D.count-1
- Cells (i + 2, 5) = d (KRR (i)). Count
- Next
- Set d = Nothing
- End Sub
- Sub Test ()
- Dim d, I&, M&, S, t$
- Randomize
- m=200000 ' recommended that no more than 200,000 of the dictionary operation speed is significantly reduced.
- s = Split ("A B C 2 D E F 3 H J K 4 L M 5 N P Q 7 R S T 8 U V W 9 X Y Z") ' Press My sequence faster
- Set d = CreateObject ("Scripting.Dictionary")
- t = "VN" & String (6, "") ' Generate password template
- Do
- For i = 3 to 8
- Mid (t, I, 1) = S (Int (RND * 30)) ' Direct substitution faster
- Next
- If t like "*[0-9]*" then if T like "vn*[a-z]*" then D (t) = "" ' Check if the number letters are included when adding a dictionary
- Loop Until D.count = M ' To exit the Do loop when no duplicates in the dictionary reach m value
- ' [A1]. Resize (m) = Application.transpose (d.keys) ' Output results note only 65536 below can be used transpose
- Set d = Nothing
- End Sub
Excel randomly generates data 2