Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Googler


Сообщения: 3665
Благодарности: 1563

Профиль | Отправить PM | Цитировать


собственно, метод, рекомендуемый Microsoft (тот самый CryptoAPI):
Код: Выделить весь код
ConsoleWrite(_Crypto_GetRandomString(12, 7) &@CRLF)

; =============================================================================
; _Crypto_GetRandomString($iLen[, $iFlag])
; -----------------------------------------------------------------------------
; Получение случайной символьной строки заданной длины
;
; $iLen       : длина получаемой строки
; $iFlag      : какие символы используются при генерации строки
;             : 1  - цифры
;             : 2  - большие английские буквы
;             : 4  - малые английские буквы
;             : 8  - основные спецсимволы
;             : 16 - дополнительные спецсимволы
;             : 32 - русские буквы
;
; При успехе  : возвращает бинарную строку
;
; При неудаче : пустая строка:
;             :   @error, @extended - код ошибки _Crypto_GetRandomBinary()
;
;             : AutoIT v3.3.0.0
; =============================================================================
Func _Crypto_GetRandomString($iLen, $iFlag = 15)
    Local $iMid, $sABC = "", $sOut = ""
    If BitAND($iFlag,1)  Then $sABC &= "0123456789"
    If BitAND($iFlag,2)  Then $sABC &= "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    If BitAND($iFlag,4)  Then $sABC &= "abcdefghijklmnopqrstuvwxyz"
    If BitAND($iFlag,8)  Then $sABC &= "~!@#$%^&*()_"
    If BitAND($iFlag,16) Then $sABC &= '`+-=",.<>/?\|[]{};:'&"'"
    If BitAND($iFlag,32) Then $sABC &= 'АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя'
    Local $iABC = StringLen($sABC)
    Local $bPWD = _Crypto_GetRandomBinary($iLen)
    If @error Then Return SetError(@error, @extended, $sOut) ; Ошибка _Crypto_GetBinary

    For $i=1 To BinaryLen($bPWD)
        $iMid = Int(BinaryMid($bPWD,$i,1))*$iABC/0x100+1
        $sOut &= StringMid($sABC, $iMid, 1)
    Next
    Return $sOut
EndFunc ; ==> _Crypto_GetRandomString

; =============================================================================
; _Crypto_GetRandomBinary($iLen)
; -----------------------------------------------------------------------------
; Получение случайной строки байтов заданной длины
;
; $iLen       : количество байтов в бинарной строке
;
; При успехе  : возвращает бинарную строку
;
; При неудаче : возвращаемое значение не является бинарной строкой:
;             :   @error=1, @extended=1 - ошибка открытия advapi32.dll
;             :   @error=1, @extended=2 - ошибка открытия kernel32.dll
;             :   @error=2 - RunTime ошибка API, @extended - код ошибки
;
;             : AutoIT v3.3.0.0
; =============================================================================
Func _Crypto_GetRandomBinary($iLen)
    Local $phProv = DllStructCreate("ulong_ptr"), $aRet
    Local $pbBuffer = DLLStructCreate("byte[" & $iLen & "]")
    ; Открытие DLL
    Local $hAdvApi = DllOpen("advapi32.dll"), $hKernel = DllOpen("kernel32.dll")
    If $hAdvApi=-1 Then Return SetError(1, 1, DllClose($hKernel)) ; Ошибка открытия advapi32.dll
    If $hKernel=-1 Then Return SetError(1, 2, DllClose($hAdvApi)) ; Ошибка открытия kernel32.dll
    ; Создание описателя криптохранилища
    $aRet = DllCall($hAdvApi, "int", "CryptAcquireContext", _
        "ptr", DllStructGetPtr($phProv), "ptr", 0, "ptr", 0, "dword", 1, "dword", 0xF0000000)
    If $aRet[0]=0 Then $aRet = DllCall($hKernel, "int", "GetLastError")
    If UBound($aRet)=1 And $aRet[0]=0x80090016 Then
        $aRet = DllCall($hAdvApi, "int", "CryptAcquireContext", _
            "ptr", DllStructGetPtr($phProv), "ptr", 0, "ptr", 0, "dword", 1, "dword", 0xF0000008)
        If $aRet[0]=0 Then $aRet = DllCall($hKernel, "int", "GetLastError")
    EndIf
    If UBound($aRet)>1 Then
        ; Генерация случайной последовательности байтов
        $aRet = DllCall($hAdvApi, "int", "CryptGenRandom", _
            "ptr", DllStructGetData($phProv, 1), "dword", $iLen, "ptr", DllStructGetPtr($pbBuffer))
        If $aRet[0]=0 Then $aRet = DllCall($hKernel, "int", "GetLastError")
        ; Закрытие описателя криптохранилища
        DllCall($hAdvApi, "long", "CryptReleaseContext", _
            "ulong_ptr", DllStructGetData($phProv, 1), "dword", 0)
    EndIf
    DllClose($hKernel)
    DllClose($hAdvApi)

    If UBound($aRet)=1 Then Return SetError(2, $aRet[0], 0) ; Ошибка API RunTime
    Return DllStructGetData($pbBuffer, 1) ; Возврат строки
EndFunc ; ==> _Crypto_GetRandomBinary

Последний раз редактировалось amel27, 13-07-2009 в 10:32. Причина: изменена обработка ошибок

Это сообщение посчитали полезным следующие участники:

Отправлено: 18:23, 12-07-2009 | #26