vendredi 16 août 2019

Does race condition produce biased pseudo random numbers?

When trying to make a legacy library reproducible (set a certain seed and you'll always get the same result), I discovered a race condition bug which looks like this

#ifndef _OPENMP
#error "OpenMP support is required for this MCVE"
#endif

#include <Rcpp.h>
#include <random>
#include <omp.h>

using namespace std;
using namespace Rcpp;

// [[Rcpp::plugins(openmp)]]
// [[Rcpp::export]]
NumericVector random_vec(int length, int n_cores) {
    /* 
     *  Returns a random vector of LENGTH.
     */
    NumericVector result(length);

    // Set up seed for each thread
    IntegerVector seeds(n_cores);
    seeds = INT_MAX * runif(n_cores);

    // !!!RACE CONDITION!!!
    int elem1, elem2;

    omp_set_num_threads(n_cores);

#pragma omp parallel shared(result)
    {
        // Seed each thread with a deterministic seed
        mt19937_64 mt(seeds[omp_get_thread_num()]);

        // I'm aware that WRE discourses the use of <random>, but I'm
        // maintaining a legacy codebase and I don't want to change
        // the existing code unless there is some drop-in replacement.
        uniform_int_distribution<> r_unif(INT_MIN / 2, INT_MAX / 2);

#pragma omp for schedule(static) nowait
        for (int i = 0; i < length; i++) {
            // Threads overwrite the values set by each other
            elem1 = r_unif(mt);
            elem2 = r_unif(mt);

            result[i] = elem1 + elem2;
        }
    }

    return result;
}

While it has been fixed, the library have been used for various research projects, so I want to estimate the impact of this bug. A few simulations indicates that the distribution of random numbers generated don't change significantly with or without a race condition, but is there a case where it actually makes a difference?




Generating a very large number of 32 bit random numbers using vb6

I have a loop of vb6 code which executes 1,000,000 plus times. Each time the loop is executed a 32 bit random number is generated. Processing time for each loop is about 250 loops per second. Problem is I am ending up with about 30,000 duplicate numbers. My understanding is that the Rnd fucntion uses the system elapsed milliseconds from system start. That should mean that the system "seed" has changed with each loop, but still getting duplicates. example: for i = 1 to 1000000 do a bunch of code get a 32 bit random number using Rnd twice in a function with a Randomize statement before each Rnd do another bunch of code next i
Any ideas? Thanks




$urandom_range does not loop

I used $urandom_range to add errors at random bit positions in data. I am sending this data to a decoder to correct the error. I used the code given by Mr. Bone here on stackoverflow. I am having trouble making it loop for every new error added. It only displays the final data and thats the one that gets sent to the decoder. I want it to iterate over a range and send all the new iterations to the decoder to work on.

module test_bench ();

parameter DATA_WIDTH = 13; 
parameter IDX_WIDTH = $clog2(DATA_WIDTH);

wire [4:0] parity_out_enc;

wire [7:0] corr_data_out;
wire [4:0] syndrome;
wire uncorr, corr;
wire flag;
wire [4:0]      vxh;
wire [4:0] parity_out;
wire [7:0] data_dec;
wire [4:0] parity_dec;
wire [IDX_WIDTH-1:0] idx_to_flip;

reg [7:0] data_enc;

initial 
begin 

    $display ("time\t parity_out_enc data_enc  idx_flip data_dec   parity_dec corr_data_out syndrome uncorr  corr vxh    flag  parity_out");  
    $monitor ("%g\t %b          %b  %d       %b   %b      %b      %b    %b        %b   %b  %b     %b", $time, parity_out_enc, data_enc, idx_to_flip, data_dec, parity_dec, corr_data_out, syndrome, uncorr, corr, vxh,                     flag, parity_out);

    data_enc = 8'b10101010;

end 

secded_8_enc encoder (parity_out_enc, data_enc);
error_inject error_module (data_enc, parity_out_enc, data_dec, parity_dec, idx_to_flip);
secded_8_dec decoder (corr_data_out, syndrome, uncorr, corr, vxh, flag, parity_out, data_dec, parity_dec);

endmodule

module error_inject (data_in, parity_in, data_out, parity_out, idx_to_flip);

parameter DATA_WIDTH = 13; 
parameter IDX_WIDTH = $clog2(DATA_WIDTH);

input [7:0] data_in;
input [4:0] parity_in;
output reg [7:0] data_out;
output reg [4:0] parity_out;
int i;

output reg [IDX_WIDTH-1:0] idx_to_flip;
reg [DATA_WIDTH-1:0] int_data;

always@(*)
begin 
for (i=0;i<10;i=i+1)
//repeat(10)
begin 
int_data = {data_in, parity_in};

idx_to_flip = $urandom_range(DATA_WIDTH-1);
$display("Flipping data bit %d", idx_to_flip);

int_data[idx_to_flip] = !int_data[idx_to_flip];
$display("bad data = %b",int_data);

 data_out = int_data[12:5];

 parity_out = int_data[4:0];
end 
end 

endmodule




Random generating of numbers doesn't work properly

I'm trying to create a programm that makes sudoku's. But when I try to let the programm place numbers at random spots it doesnt use every position.

I tried to use rand(); with srand(time(0)); and randomnumbergenerators from random

In the Constructor i use this:

mt19937_64 randomGeneratorTmp(time(0));
randomGenerator = randomGeneratorTmp;
uniform_int_distribution<int> numGetterTmp(0, 8);
numGetter = numGetterTmp;

While I have randomGenerator and numGetter variable so i can use them in another function of the sudoku object. And this is the function where i use the random numbers:

bool fillInNumber(int n){
     int placedNums = 0, tries=0;
     int failedTries[9][9];
     for(int dim1=0;dim1<9;dim1++){
         for(int dim2=0;dim2<9;dim2++){
             failedTries[dim1][dim2] = 0;
         }
     }

     while(placedNums<9){
         int dim1 = numGetter(randomGenerator);
         int dim2 = numGetter(randomGenerator);
         if(nums[dim1][dim2]==0){
             if(allowedLocation(n,dim1,dim2)){
                 nums[dim1][dim2] = n;
                 placedNums++;
             } else {
                 failedTries[dim1][dim2]++;
                 tries++;
             }
         }
         if(tries>100000000){
             if(placedNums == 8){
                 cout<< "Number: " << n << endl;
                 cout<< "Placing number: " << placedNums << endl;
                 cout<< "Dim1: " << dim1 << endl;
                 cout<< "Dim2: " << dim2 << endl;
                 printArray(failedTries);
             }
             return false;
         }
     }
     return true;
}

( The array "failedTries" just shows me which positions the programm tried. and most of the fields have been tried millions of times, while others not once)

I think that the random generation just repeats itself before it used every numbercombination, but i dont know what im doing wrong.




based on condition=True in an column filling random values to a particular column pandas python

I need to work on a column, and based on a condition (if it is True ), need to fill some random numbers for the entry(not a constant string/number ). Tried with for loop and its working, but any other fastest way to proceed similar to np.select or np.where conditions ?

I have written for loop and its working: The 'NUMBER' column have here few entries with greater than 4, i need to replace them by any float in between (120,123). I have used np.random.uniform and its working too.

    for i in range(0,len(data['NUMBER'])):
        if data['NUMBER'][i] >=1000:
        data['NUMBER'][i]=np.random.uniform(120,123)\

    '''The o/p for this code fills each entries with different values 
     between (120,123) in random,after replacement the entries are'''
     0          7.139093
     1         12.592815
     2         12.712103
     3        **120.305773**
     4         11.941386
     5         **122.548703**
     6         6.357255.............etc

    ''' but while using codes using np.select and np.where as shown below(as 
     it will run faster) --> the result was replaced by same number alone 
     for all the entries satisfying the condition. for example instead of 
     having different values for the indexes 3 and 5 as shown above it 
     have same value of any b/w(120,123 ) for all the entries. please 
     guide here.'''

    data['NUMBER'] =np.where(data['NUMBER'] >= 1000,np.random.uniform(120,123), data['NUMBER'])

    data['NUMBER'] = np.select([data['NUMBER'] >=1000],[np.random.uniform(120,123)], [data['NUMBER']])




sodium VS csprng

I've been looking for the best CSPRNG in javascript/nodejs.

window.crypto.getRandomValues() seems to not be always available and may cause some issues if not;

There's also a discussion about some issues with crypto.randomBytes() in https://github.com/nodejs/node/issues/5798;

Then I've found two approaches:

var random1 = require('sodium').Random.randombytes_buf(32);
and
require('csprng')(256, 36); //256 is the number of the bits and 36 is the base I'm using now (if it was 2, only 0's and 1's would be printed)

Which one is the best between random1 and random2?




How to select a random URL form extracted URL list

I am trying to extract the proxy urls and would like to use one random url

import requests
from lxml import html
import random

def get_proxy():
    url = 'https://sslproxies.org/'
    req = requests.get(url)
    iptree = html.fromstring(req.content)
    iprange = range(1,20)
    for ips in iprange:
        https = iptree.xpath('//*[@id="proxylisttable"]/tbody/tr[%d]/td[7]//text()'%ips)
        iptd = iptree.xpath('//*[@id="proxylisttable"]/tbody/tr[%d]/td[1]//text()'%ips)
        port = iptree.xpath('//*[@id="proxylisttable"]/tbody/tr[%d]/td[2]//text()'%ips)
        for htp in https:
            if htp=="yes":
                for (ips, por) in zip(iptd, port):
                    iplist = ("https://" + ips + ":" + por)
                    print(iplist)

get_proxy()

i want to assign one random URL to a string and use it in my web scraper, but i am unable to select random one