alibek писал(а):Ты учти, что RND дает не случайное число, а ПСЕВДОСЛУЧАЙНОЕ. И если знать алгоритм его формирования, можно подобрать такое значение Randomize, что данная ситуация как-раз и возникнет.
Ты же сам сказал, что этим никто не будет заниматься! Проще крякнуть и/или выложить халявный ключь!
alibek писал(а):Вероятность, что 1000 раз подряд будет выпадать числа в диапазоне 0...31 равна (примерно) 8.128548625558E-904, но дело не в вероятности, а в принципиальной возможности такой ситуации. Мало ли, может математический сопроцессор глюк словит и всегда будет RND()=0.
Согласен.
Но, глюки проца, это уже не наша проблемма.
А если уж исключать принцыпиальную возможность, то можно
Do ... Loop заменить на
For ... Next с
Exit For и вслучае выхода по завершению цикла, выдавать ошибку.
alibek писал(а):Насчет твоего доработанного варианта - а теперь сравни его с моим? И еще учти, что константы cLetter и прочие можно использовать в других целях (у меня, к примеру, они используются для орфографического анализа), т.е. их можно исключить из листинга.
Сравнил... Вот тебе ещё мой вариант, твоего варианта -- сравни...
- Код: Выделить всё
Function GenerateKeyPhrase(Optional ByVal PhraseLength As Long) As String
Dim res As String, I As Long, C As Byte, S As String, N As Long, TMP As Long
If PhraseLength = 0 Then
Randomize
PhraseLength = 20 + Rnd * 20
End If
Randomize
TMP = 1 + Rnd * 2
Select Case TMP
Case 1
S = cRLetter
Case 2
S = cLLetter
Case 3
S = cDigits
End Select
For I = 1& To PhraseLength
TMP = Len(S) - 1&
C = 1 + Rnd * TMP
N = N + 1&
If N >= Rnd * 10 And N > 1& Then
C = 0
N = 0&
Randomize
If Rnd > 0.5! Then
S = cRLetter
Else
S = cLLetter
End If
If Rnd < 0.25! Then
S = S & cDigits
End If
End If
If C = 0 Then
res = res & vbSpace
Else
If N = 1& Then
S = Mid$(S, C, 1)
res = res & UCase$(S)
Else
S = Mid$(S, C, 1)
res = res & LCase$(S)
End If
End If
Next I
GenerateKeyPhrase = res
End Function
... и всёравно у меня быстрее. Ж8-D
А вот константы из листинга ненадо исключать, если они юзаются -- должны быть, а то что они ещё где-то используются, так это ПЛОХО!
alibek писал(а):И вообще, лучше объясняться фактами.
Разница в полсекунды на десять тысяч вызовов помоему не принципиальна.
1) Такие вещи "достовернее" запускать скомпилёнными (если что -- заменить
Debug.Print на
Me.Print).
2) У меня длина строки в интервале (10;50), а у тебя (20;40).
2) Тут не просто полсекунды, а моё в два раза быстрее работает. ;-)