1

一連の座標に基づいて反復可能な擬似乱数を生成する必要があるため、特定のシードを使用して、特定の座標に対して常に同じ値を生成します。

シードには次のようなものを使用すると考えました。

/* 64bit seed value*/
struct seed_cord {
    uint16 seed;
    uint16 coord_x_int;
    uint16 coord_y_int;
    uint8  coord_x_frac;
    uint8  coord_y_frac;
}

は座標coord_x_intの整数部分で、小数部分は で与えられcoord_x_frac / 0xFFます。seedランダムに事前に決定された値です。

しかし、PRNG のすべての複雑さを理解しようとするのは少々圧倒されることは認めざるを得ません。私が試みていることの良いジェネレーターは何でしょうか?

このスキームを使用して Java の PRNG を簡単な groovy スクリプトでテストしたところ、次の結果が得られました。

ランダムにシードされた画像

明らかに、これはまともなランダム性とは言えません。

私が使用したスクリプトは次のとおりです。

import java.awt.image.BufferedImage
import javax.imageio.ImageIO

short shortSeed = new Random().next(16) as short

def image = new BufferedImage(512, 512, BufferedImage.TYPE_BYTE_GRAY)
def raster = image.getRaster()

//x
(0..1).each{ x ->
(0..255).each{ xFrac ->
//y
(0..1).each{ y ->
(0..255).each{ yFrac ->

long seed = (shortSeed as long) << 48 |
            (x as long)         << 32 |
            (y as long)         << 16 |
            (xFrac as long)     <<  8 |
            (yFrac as long)

def value = new Random(seed).next(8)
raster.setSample( (x? xFrac+256 : xFrac), (y? yFrac+256 : yFrac), 0 , value)

}}}}

ImageIO.write(image, "PNG", new File("randomCoord.png"))
4

4 に答える 4

1

あなたが本当に512x512だけを見ているなら、それはええと...あなたが興味を持っている218ピクセル。

優れたoleMD5(128ビット出力)を備えたその種の人口のための十分なスペースがあります。

必要な出力の種類であれば、整数の下位32ビットを取ることができます。実際、少なくともintと同じ大きさの出力スペースを持つあらゆる種類のハッシュアルゴリズムで十分です。

今、あなたが妄想的であるならば、あなたはあらゆる種類の楽しいことをすることができます。座標のハッシュから始めて、結果を安全な乱数ジェネレーター(java.security.SecureRandom)にフィードします。次に、誕生日を(x + y)回連結したソルトで1000回ハッシュします。

冗談はさておき、乱数ジェネレーターは、シードの小さな変化に基づいて、必ずしも大きく変化する結果をもたらすとは限りません。それらは、繰り返される前に、生成された数値の非常に非常に長いチェーンを持つように設計されていますが、それらのチェーンは、数値空間にかなり均等に分散されています。

一方、SecureRandomは、シードに関してカオス的であるという追加機能を持つように設計されています。

于 2011-05-24T08:48:11.017 に答える
0

このタスクには、AES などの暗号化を使用できます。シードをパスワードとして使用し、座標をデータ ブロックとして構造化し、暗号化します。暗号化されたブロックは乱数になります (実際にはその一部を使用できます)。このアプローチはFortuna PRNGで使用されます。データのランダム アクセスが必要なディスク暗号化にも同じアプローチを使用できます ( Fortuna PRNG を使用したカウンター モードでの AES によるランダム アクセス暗号化を参照してください) 。

于 2012-05-14T08:50:19.897 に答える
0

ほとんどの言語には、特定のシードでジェネレーターを初期化できる PRNG パッケージ (または 2 つ) があります。PRNG は、より大きな暗号化パッケージの一部として見つかることもよくあります。それらは、汎用ライブラリにあるものよりも少し強力になる傾向があります。

于 2011-05-23T14:15:55.547 に答える
0

私が作成したこのようなプログラムを使用して、座標を選択するように変更します。

REM $DYNAMIC
COMMON SHARED n%, rbuf%, sz%, sw%, p1$
DECLARE SUB initialize ()
DECLARE SUB filbuf ()
DECLARE SUB setup ()
DECLARE FUNCTION Drnd# ()
DECLARE SUB core ()
DECLARE SUB modify ()
DIM SHARED pad1(340) AS STRING * 1
DIM SHARED trnsltr(66) AS STRING * 1 ' translates a 0-67 value into a pad character
DIM SHARED trnslt(255) AS INTEGER  'translates a pad value to 0-67 value -1 if error
DIM SHARED moders(26) AS INTEGER 'modding function prim number array
DIM SHARED moders2(26) AS INTEGER 'modding function prim number array
DIM SHARED ranbuf(1 TO 42) AS DOUBLE 'random number buffer if this is full and rbuf %>0
REM then this buffer is used to get new random values
REM rbuf% holds the index of the next random number to be used
REM subroutine setup loads the prime number table
REM from the data statements to be used
REM as modifiers in two different ways (or more)
REM subroutine initialize primes the pad array with initial values
REM transfering the values from a string into an array then
REM makes the first initial scrambling of this array
REM initializing pad user input phase:
CLS
INPUT "full name of file to be encrypted"; nam1$
INPUT "full name of output file"; nam2$
INPUT "enter password"; p2$
rbuf% = 0
n% = 0: sw% = 0
p3$ = STRING$(341, "Y")
p1$ = "Tfwd+-$wiHEbeMN<wjUHEgwBEGwyIEGWYrg3uehrnnqbwurt+>Hdgefrywre"
p1$ = p2$ + p1$ + p3$
PRINT "hit any key to continue any time after a display and after the graphic display"
p1$ = LEFT$(p1$, 341)
sz% = LEN(p1$)
CALL setup
CALL initialize
CLS
ibfr$ = STRING$(512, 32)
postn& = 1
OPEN nam1$ FOR BINARY AS #1
OPEN nam2$ FOR BINARY AS #2
g& = LOF(1)
max& = g&
sbtrct% = 512
WHILE g& > 0
LOCATE 1, 1
PRINT INT(1000 * ((max& - g&) / max&)) / 10; "% done";
IF g& < 512 THEN
ibfr$ = STRING$(g&, 32)
sbtrct% = g&
END IF
GET #1, postn&, ibfr$
FOR ste% = 1 TO LEN(ibfr$)
geh% = INT(Drnd# * 256)
MID$(ibfr$, ste%, 1) = CHR$(geh% XOR ASC(MID$(ibfr$, ste%, 1)))
NEXT ste%
PUT #2, postn&, ibfr$
postn& = postn& + sbtrct%
g& = g& - sbtrct%
WEND
CLOSE #2
CLOSE #1
PRINT "hit any key to exit"
i$ = ""
WHILE i$ = "": i$ = INKEY$: WEND
SYSTEM
END
DATA 3,5,7,9,11,13,17,19
DATA 23,29,33,37,43,47
DATA 53,59,67,71,73,79,83
DATA 89,91,97,101,107,109
DATA 43,45,60,62,36

REM $STATIC
SUB core
REM shuffling algorythinm
FOR a% = 0 TO 339
m% = (a% + 340) MOD 341: bez% = trnslt(ASC(pad1(340)))
IF n% MOD 3 = 0 THEN pad1(340) = trnsltr((2 * trnslt(ASC(pad1(a%))) + 67 -   trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 1 THEN pad1(340) = trnsltr((2 * (67 - trnslt(ASC(pad1(a%)))) + 67 - trnslt(ASC(pad1(m%)))) MOD 67)
IF n% MOD 3 = 2 THEN pad1(340) = trnsltr(((2 * trnslt(ASC(pad1(a%))) + 67 - trnslt(ASC(pad1(m%)))) + moders(n% MOD 27)) MOD 67)
pad1(a% + 1) = pad1(m%): n% = (n% + 1) MOD 32767
pad1(a%) = trnsltr((bez% + trnslt(ASC(pad1(m%)))) MOD 67)
NEXT a%
sw% = (sw% + 1) MOD 32767
END SUB

FUNCTION Drnd#
IF rbuf% = 0 THEN
CALL core
CALL filbuf
IF sw% = 32767 THEN CALL modify
END IF
IF rbuf% > 0 THEN yut# = ranbuf(rbuf%)
rbuf% = rbuf% - 1
Drnd# = yut#
END FUNCTION

SUB filbuf
q% = 42: temp# = 0
WHILE q% > 0
FOR p% = 1 TO 42
k% = (p% - 1) * 8
FOR e% = k% TO k% + 7
temp# = temp# * 67: hug# = ABS(trnslt(ASC(pad1(e%)))): temp# = temp# + hug#
NEXT e%
IF temp# / (67 ^ 8) >= 0 AND q% < 43 THEN
ranbuf(q%) = temp# / (67 ^ 8): q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
rbuf% = 42
END SUB

SUB initialize
FOR a% = 0 TO 340
pad1(a%) = MID$(p1$, a% + 1, 1)
NEXT a%
FOR a% = 0 TO 340
LOCATE 1, 1
IF a% MOD 26 = 0 THEN PRINT INT((340 - a%) / 26)
sum% = 0
FOR b% = 0 TO 340
qn% = INT(Drnd# * 81)
op% = INT(qn% / 3)
qn% = qn% MOD 3
IF qn% = 0 THEN sum% = sum% + trnslt(ASC(pad1(b%)))
IF qn% = 1 THEN sum% = sum% + (67 + 66 - trnslt(ASC(pad1(b%)))) MOD 67
IF qn% = 2 THEN sum% = sum% + trnslt(ASC(pad1(b%))) + moders(op%)
NEXT b%
pad1(a%) = trnsltr(sum% MOD 67)
NEXT a%
n% = n% + 1
END SUB

SUB modify
REM modifier shuffling routine
q% = 26
temp# = 0
WHILE q% > -1
FOR p% = 1 TO 27
k% = (p% - 1) * 4 + 3
FOR e% = k% TO k% + 3
temp# = temp# * 67
hug# = ABS(trnslt(ASC(pad1(e%))))
temp# = temp# + hug#
NEXT e%
IF (temp# / (67 ^ 4)) >= 0 AND q% > -1 THEN
SWAP moders(q%), moders(INT(27 * (temp# / (67 ^ 4))))
q% = q% - 1
END IF
temp# = 0
NEXT p%
WEND
END SUB

SUB setup
FOR a% = 0 TO 26
READ moders(a%)
moders2(a%) = moders(a%)
NEXT a%
REM setting up tables and modder functions
FOR a% = 0 TO 25
trnsltr(a%) = CHR$(a% + 97)
trnsltr(a% + 26) = CHR$(a% + 65)
NEXT a%
FOR a% = 52 TO 61
trnsltr(a%) = CHR$(a% - 4)
NEXT a%
FOR a% = 62 TO 66
READ b%
trnsltr(a%) = CHR$(b%)
NEXT a%
FOR a% = 0 TO 255
trnslt(a%) = -1
NEXT a%
FOR a% = 0 TO 66
trnslt(ASC(trnsltr(a%))) = a%
NEXT a%
RESTORE
END SUB

drand# を呼び出すと、0 から 1 までの乱数が得られます。必要なベクトルごとに必要な範囲を掛けるだけです。特定の制限 p1$ は、最終的に変更されたパスワードが含まれる場所です drand# 自体は、実際にはそれ自体のクローンである別のサブルーチンを呼び出します。これは、生成される数値が本当にランダムであることを保証するために機能する、ある種のシャッフルを備えています。値のテーブルもあります。追加される値に追加されるこれらすべての合計により、RNG は、使用しない場合よりも何倍もランダムになります。

この RNG は、最初に設定されたパスワードのわずかな違いに非常に敏感です。ただし、最初にセットアップを呼び出して、乱数ジェネレーターを「ブートストラップ」するように初期化する必要があります。この RNG は、ランダム性のすべてのテストに合格する真の乱数を生成します。次に、カードのデッキを手でシャッフルします。これは、サイコロを振るよりもランダムです..これが同じパスワードを使用すると、ベクトルの同じシーケンスが得られることを願っています

このプログラムは、安全な暗号化乱数ジェネレーターとして現在使用されているのではなく、ランダムなベクトルを選択するために少し変更する必要があります...

于 2012-01-27T15:19:31.157 に答える