Integer class>>randomBits: Q

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Integer class>>randomBits: Q

Boris Popov, DeepCove Labs (SNN)

I realize this is deprecated by virtue of method being in that category, but there’s no further comment as to why, hence the below inquiry.

 

Parcel loadParcelByName: 'CiphersBase'.

int := Integer randomBits: 4096.

(int printStringRadix: 2) inject: Dictionary new

                into:

                                [:dict :char |

                                dict

                                                at: char put: (dict at: char ifAbsent: [0]) + 1;

                                                yourself].

 

$0 "16r0030":  84

$1 "16r0031":  4012

 

Naively, I would have expected close to 50/50 split, not 98/2?

 

Running the above to get back just 8 bytes, the bits appear to be much closer split, often times exact down the middle.

 

$0 "16r0030":  31

$1 "16r0031":  32

 

-Boris

Sr. Software Engineer

DeepCove Labs

4th floor, 595 Howe Street

Vancouver, BC V6C 2T5

Canada

 


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Integer class>>randomBits: Q

Henrik Sperre Johansen
On 18.10.2012 15:22, Boris Popov, DeepCove Labs wrote:

I realize this is deprecated by virtue of method being in that category, but there’s no further comment as to why, hence the below inquiry.

 

Parcel loadParcelByName: 'CiphersBase'.

int := Integer randomBits: 4096.

(int printStringRadix: 2) inject: Dictionary new

                into:

                                [:dict :char |

                                dict

                                                at: char put: (dict at: char ifAbsent: [0]) + 1;

                                                yourself].

 

$0 "16r0030":  84

$1 "16r0031":  4012

 

Naively, I would have expected close to 50/50 split, not 98/2?

 

Running the above to get back just 8 bytes, the bits appear to be much closer split, often times exact down the middle.

 

$0 "16r0030":  31

$1 "16r0031":  32

  vwnc mailing list [hidden email] http://lists.cs.uiuc.edu/mailman/listinfo/vwnc

The function is bugged.
blockSize does not return the number of random bits generated by each next call, but is a much smaller number.
So when you, say, shift a number by 40, then or: in a new 320bit number, and do so for every 40 bits the asked for size is above the original 320 in the first next value, you end up with most of them being 1's.

Note: Even if it worked as intended, it would be bugged, as the return number always have high bit = size

A correct implementation (albeit slower, and still depending on DSSRandom to return a high-quality random) would be something like:
randomBits2: size
| random bits |
    random := Security.DSSRandom default.
    bits := random next.
    [    bits highBit < size
    ] whileTrue: [|nextInput|
        nextInput := random next.
        bits := (bits bitShift: nextInput highBit -1) bitOr: (nextInput bitXor: 1 << nextInput highBit)  ].
    ^(bits bitShift: (size - bits highBit -1)) bitXor: 1 << bits highBit

Cheers,
Henry

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Integer class>>randomBits: Q

Henrik Sperre Johansen
On 19.10.2012 16:55, Henrik Sperre Johansen wrote:

A correct implementation (albeit slower, and still depending on DSSRandom to return a high-quality random) would be something like:
randomBits2: size
| random bits |
    random := Security.DSSRandom default.
    bits := random next.
    [    bits highBit < size
    ] whileTrue: [|nextInput|
        nextInput := random next.
        bits := (bits bitShift: nextInput highBit -1) bitOr: (nextInput bitXor: 1 << nextInput highBit)  ].
    ^(bits bitShift: (size - bits highBit -1)) bitXor: 1 << bits highBit
Speaking of bugs:
randomBits2: size

    | random bits |
    random := Security.DSSRandom default.
    bits := random next.
    [bits highBit < size] whileTrue:
            [| nextInput |
            nextInput := random next.
            bits := (bits bitShift: nextInput highBit - 1)
                        bitOr: (nextInput bitXor: 1 << (nextInput highBit - 1))].
    bits := bits bitShift: size - bits highBit +1.
    ^bits bitXor: 1 << (bits highBit - 1)

is closer to what I meant, after actually running the code. :)

A way to see the thingy in the Note:, is inspecting
|b|
b := Bag new.
10000 timesRepeat: [b add: (Integer randomBits: 3)].
b

and notice how delightfully rare 0-3 are compared to 4-7.

So there's good reason why this is deprecated :)

Cheers,
Henry

_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc
Reply | Threaded
Open this post in threaded view
|

Re: Integer class>>randomBits: Q

Boris Popov, DeepCove Labs (SNN)
In reply to this post by Henrik Sperre Johansen

Henrik,

 

This all makes more sense to me now. I realized quickly that this wasn’t quite what I needed anyhow since I was looking to generate numbers whose base32 encoded value would be exactly 9 (for example) characters long, so what I was really looking for is a random number in the range 16r10000000000 (100000000) - 16r1FFFFFFFFFFF (ZZZZZZZZZ); too bad one can’t just pass a DSSRandom instance to #atRandom:,

 

(16r10000000000 to: 16r1FFFFFFFFFFF) atRandom: DSSRandom default

 

-Boris

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Henrik Sperre Johansen
Sent: Friday, October 19, 2012 11:13 AM
To: [hidden email]
Subject: Re: [vwnc] Integer class>>randomBits: Q

 

On 19.10.2012 16:55, Henrik Sperre Johansen wrote:


A correct implementation (albeit slower, and still depending on DSSRandom to return a high-quality random) would be something like:
randomBits2: size
| random bits |
    random := Security.DSSRandom default.
    bits := random next.
    [    bits highBit < size
    ] whileTrue: [|nextInput|
        nextInput := random next.
        bits := (bits bitShift: nextInput highBit -1) bitOr: (nextInput bitXor: 1 << nextInput highBit)  ].
    ^(bits bitShift: (size - bits highBit -1)) bitXor: 1 << bits highBit

Speaking of bugs:
randomBits2: size

    | random bits |
    random := Security.DSSRandom default.
    bits := random next.
    [bits highBit < size] whileTrue:
            [| nextInput |
            nextInput := random next.
            bits := (bits bitShift: nextInput highBit - 1)
                        bitOr: (nextInput bitXor: 1 << (nextInput highBit - 1))].
    bits := bits bitShift: size - bits highBit +1.
    ^bits bitXor: 1 << (bits highBit - 1)

is closer to what I meant, after actually running the code. :)

A way to see the thingy in the Note:, is inspecting
|b|
b := Bag new.
10000 timesRepeat: [b add: (Integer randomBits: 3)].
b

and notice how delightfully rare 0-3 are compared to 4-7.

So there's good reason why this is deprecated :)

Cheers,
Henry


_______________________________________________
vwnc mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/vwnc