Need an Algorithm to generate Serialnumber - algorithm

I want to generate 16-digits hexadecimal serial-number like: F204-8BE2-17A2-CFF3.
(This pattern give me 16^16 distinct serial-number But I don't need all of them)
I need you all to suggest me an algorithm to generate these serial-numbers randomly with an special characteristic which is:
each two serial-numbers have (at-least) 6 different digits
(= It means if you are given two most similar serial-number, they should still have difference in 6 indexes)
I know that a good algorithm with this characteristic needs to remember previously generated serial-numbers and I don't want that much.
In fact, I need an algorithm which do this with least probability for a chosen pair to collide (less than 0.001 seems sufficient )
PS:
I've just tried to create 10K string randomly using MD5 hash and It gave similar string( similar=more than 3 same digits) with 0.00018 probability.

It is possible to construct a correct generator without having to remember all previously generated codes. You can generate serial numbers that are spaced 6 characters apart by using Hamming code. A hamming code can be designed to arbitrarily space out two distinct generated values. Obviously, the greater the distance, the higher redundancy you will have to use, resulting in more complex code and longer numbers.
First you design a hamming code to your liking, that encodes a number into a sequence of hexadecimal digits and then you can take any sequence of numbers and use it as a seed, such as prime numbers. You just always need to remember, what number was used last and use the next one.
That being said, if you don't need to properly ensure minimal distance of two serials, and would settle for a small error, I would suggest that any half decent hash function or cypher should produce decently spaced out outputs. Therefore the first thing I would try to do is to take MD5 or SHA hashes and test-drive them on numbers 1 - 1000. My hopes are, the results will be quite satisfactory.

I suggest you look into the ANSI X9.17 pseudorandom bit generator. An algorithmic sketch is given in these slides. ANSI X9.17 generates 64-bit pseudorandom strings which is what you want.
A revised and enhanced version of this generator was approved by NIST. Please have a look at this page.
Now whether you use ANSI X9.17 generator, another generator, or develop your own, it's a good idea to have the generator pass some statistical tests in order to ensure the quality of its pseudorandom bits.
Example tests include the ENT battery, the DIEHARD battery, and the NIST battery.

Related

How can we know if a sequence is pseudo random or true random?

Given a sequence (ex 1 4 3 5 3 6 .....) and its range (ex 1-10 ), knowing that it is generated from a "Random Generator".
How to know whether that "Random Generator" is pseudo random or true random (Assuming the sequence is infinite).
Obviously, you can't. For one thing -- the only thing you can actually observe is a finite sequence of numbers. Every possible observed sequence will have a non-zero probability of occurring even if the sequence is genuinely random. You can observe 20 tails in a row and that is completely consistent with tossing a genuinely fair coin. Conversely, any finite sequence, no matter how random it looks, can be generated by a deterministic process.
Having said that, there are various statistical tests (most famously the Diehard tests developed by George Marsaglia) which can be applied to a sequence. They can't certify a sequence as random or pseudorandom with certainty, but poorly designed pseudorandom number generators will do poorly on these tests. On the other hand, if a sequence does well on these tests then it will be more or less impossible (without knowing the source of the numbers) to tell if it came from a pseudorandom number generator or a genuinely random source. The entire point of 50+ years of research is to ensure that the answer to your question is effectively "No - you can't tell".
To add to the well written answer of John, I would like to add a few remarks.
First, I do believe that out of every "Random Generator", as you name them, none of the random number that you'll get are truly random. Even further, we do not know a way to procude a true "random" sequence of number. The only true random that you can obtain comes from quantic particles as they are not determinist and can be considered at some extent as random. When you have a website or a program that gives you a random number, it comes from a determinist method, which could theoretically be deduced, if we knew all of the initial conditions. Some of the more "random" algorithms, for example, use the variation of the atmosthere as a way to produce a seemingly random result (see this random generator for example). And yet, if we could get all of the parameters used on an instant T, you could theoretically "guess a random number".
What you can do though, if you do not recognise a pattern in your data, is to do a statistical analysis of your data. As John said, there are numerous methods to recognise a correlation between your random values, and you could get some informations about your data. You could use tools on many mathematical programming tools (Matlab, Maple for example ...) to try to analyse your data. But, in the end, you might never be able to tell with a full certainty the veracity of your results.
So, just like John said, NO, you can't.

How do you make an algorithm for a Random Number Generator?

According to a teacher of mine in-order to do this you make two arrays with numbers, possessing several decimals. One positive array and one negative.
Array 1 [0] = e.g 1.5739
Array 2 [0] = e.g -5.31729
Then you find current time
201305220957 or May 22,2013 at 9:57 AM
And use this equation:
(201305211647*1.5739)--5.31729
-Then you use absolute value and round to 1.0 decimal place and you have your number
Is it true that in most generators the value is dependent on time?
Bottom line up front - Generating random numbers is really hard to do right, and has badly burned some seriously smart people (John Von Neumann for one). Normal people shouldn't try to create their own RNG algorithms. It requires expertise in number theory, probability & statistics, and numerical computation. Unless you qualify in all three fields, you're much better off using algorithms developed by people who are. If you want to know how to do it right you can find lots of good info at http://en.wikipedia.org/wiki/Random_number_generation and http://en.wikipedia.org/wiki/Pseudorandom_number_generator.
Speaking bluntly, your teacher is totally clueless about this topic.
If you need to generate random numbers for encryption, or statistical purposes - you need to get a well studied generator. One I like is the Mersenne Twister, that has very nice statistical properties, is fast to run and easy to code.
If you just need a reasonably random generator - for example to make things appear random in a game - you can use the classic "Linear Congruent Generator" which is trivial to write and produces pretty random looking output. ( Not safe for heavy duty computation ).
The LCG generator:
int seed = 0x333; // chose any number.
int random() { seed = ( seed * 69069 ) + 1; return seed; }
There are several numbers you can use instead of 69069. But don't pick your own. Chose one from here if you don't like 69069.
http://en.wikipedia.org/wiki/Linear_congruential_generator
The wikipedia has a lot of great pages devoted to random number generation (RNG). One page is devoted to just listing the various types of random number generators used throughout history. One of the earliest and weakest is known as the Middle Square method - easy to implement in programming and suitable for many low level tasks. Some computers have a linear feedback shift register (LFSR) built into the circuitry for random number generation, but its not very advanced. One of the more modern generators (not the most modern), and which is considered cryptographically secure (in the sense of how unpredictable it is), is known as the Mersenne Twister.
Properly, these are pseudorandom number generators (PRNG), because they arent truly random. They arent truly random because computers are deterministic machines (state machines); no predetermined algorithm can be programmed to generate truly random numbers from a known prior state.
That said, the invention of true random number generator (TRNG) hardware circuitry (typically analog) does exist, and are approached in different ways. From checking ambient conditions such as temperature and pressure, to phenomenon a more nuanced and bit more subject to conditions atomic/quantum, such as what state a multistable circuit with feedback settles in. Most modern personal computers do not use this and, if they do, probably only use it to find the seed value for PRNGs. Then, you also have RNG programs that check through an internet connection, to find random number servers online, most of which use TRNGs. You can even rely on lookup tables from real world phenomenon that have been documented; lookup tables is very old school.
Pseudorandom number generators only have the appearance of randomness, namely, they follow a particular distribution and the ability to predict future values from prior ones is not easy. There are a set of diehard tests which have the sole purpose of testing the quality of a random number generator. In general, though, all a PRNG is, is an algorithm that produces a sequence of integers. Ideally, we are looking for an algorithm that produces a sequence of numbers which are suitably unpredictable (this is the hardest part) from prior terms in the sequence, while also following a particular distribution (uniform, typically), meaning that every value in a range is produced in equal proportion.
In general, its a trivial task to convert one distribution into another, regardless if its TRNG or PRNG. Uniform discrete integer distributions (which is what PRNGs generate) can easily be extended or compressed to span any arbitrary interval of integers using a variety of scaling techniques that preserve uniformity, or converted into uniform floating points distributions by randomly choosing a large integer and scaling it down into a float, etc.
Uniform floating point numbers can easily be converted to any other non-uniform distribution such as the Normal, Chi-Square, exponential, etc., using a variety of methods, such as Inverse Transform sampling, Rejection sampling, or simple algebraic relationships on distributions (e.g. the Chi-Square is simply the sum of the squares of independent normal distributions). Additionally some distributions can be suitably approximated using simple mathematical functions applied to a uniform float.
Ultimately the hardest part and the heart of most studies in the subject is in the generation of those uniformly distributed integers, that form the basis of all other distributions.
There is nothing fundamentally wrong with using clock time to get an initial seed value, for example. Id favor using the lower three or four significant digits of the time expressed in microseconds, however, for something suitably unpredictable. Or using the LFSR in a computer for the same purpose, of getting a more advanced algorithm jump started.

Make CURAND generate positive different random numbers less than a specific number

I am trying to use CURAND library to generate random numbers which are completely independent of each other. Hence I want to give different seeds to each thread.
So, Question 1: How do I give different seeds to each thread?(Is there some time function in CUDA which I can use?)
Now I also want to generate this random number between a range i.e 0 to 10000. How do I accomplish that to happen.
Currently I am using curand_normal (as I want to have numbers from normal distribution) but its giving me negative and same numbers which I do not want.
Setting different seeds is not a statistically sound way to get independent (non-correlated) random numbers (with any single random number generator). You would be better off selecting different sub-sequences of a single sequence, and most random number libraries will allow you to do that, including cuRAND.
Check out the examples in the CUDA SDK, for example the EstimatePiP or EstimatePiInlineP examples use cuRAND to generate pseudo-random numbers.
For the second part of your question, as mentioned in the cuRAND manual the curand_normal() routines return Normally distributed numbers with mean 0.0 and standard deviation 1.0 (i.e. Standard Normal Distribution). Clearly that means that you will have ~50% negative numbers.
It doesn't make sense to specify a fixed range along with the Normal distribution. You either want some other distribution (e.g. Uniform) with the fixed range or else you want the Normal distribution with a specific mean and standard distribution. To get from the Standard Normal to your target mean/std.dev. you simply multiply the random draw by the target standard deviation and add the target mean.

Why are some random() functions deemed "not secure?"

I've heard people being warned all over the place not to rely on a language's random() function to generate a random number or string sequence "for security reasons." Java even has a SecureRandom class. Why is this?
When people talk about predicting the output of a random number generator, they don't even need to get the actual "next number". Even something subtle like noticing that the random numbers aren't evenly distributed, or that they never produce the same number twice in a row, or that "bit 5 is always set", can go a long way towards turning an attack based on guessing a "random" number from taking years, to taking days.
There is a tradeoff, generally, too. Without specific hardware to do it, generating large quantities of random numbers quickly can be really hard, since there isn't enough "randomness" available to the computer so it has to fake it.
If you're not using the randomness for security (cryptography, passwords, etc), but instead for things like simulations or numerical work, then it doesn't matter too much if they're predictable, only that they're statistically random.
Almost every random number generator is 'pseudo random' in that it uses a table of random numbers or a predictable formula. A seed is sometimes used to "start" the random sequence at a specific point, e.g. seedRandom(timer).
This was especially prevalent in the days of BAsIC programming, because it's random number generator always started at exactly the same sequence of numbers, making it unusable for any kind of GUID generation.
Back in the day, the Z-80 microprocessor had a truly random number generator, although it was only a number between 0 and 127. It used a processor cycle function and was unpredictable.
Pseudo-random numbers that can be determined in advance can lead to security holes that are vulnerable to a random number generator attack.
Predictability of a random number is a big issue. Most "random" functions derive their value from time. Given the right set of conditions you could end up with two "random" numbers of a large value that are the same.
In windows .NET world CPRNG (Cryptographically secure pseudo random number generator) can be found in System.Security.Cryptography.RandomNumberGenerator through underlying win32 APIs
In Linux there is a random "device"

True random vs. Pseudo Random (can you pseudo-random true-randomness)

Ok, so this question involves a bit of a forward. Bear with me.
There's this website random.org (and others like it) that claim to use some sort of quantum process or another to produce true random numbers.
If one were to query this site over and over and develop a massive log of true random numbers. This log is then rearranged by a program to mix it up as randomly as it can. Is the resulting output less random than when it started? By how much?
Any good/cheap further reading on the subject?
Reordering random numbers by a fixed permutation does not change the degree of randomness.
So if you have a perfect random number source, the same bits reshuffled will be equally random. This will be true if whether the "shuffle" is a fixed reordering (e.g. reversing all the bits) or a shuffle generated by a pseudo-random number generator (which is really a very obfuscated way of defining a fixed re-ordering from some initial seed).
This is provable from the underlying maths - if you reorder a set of truly independent identically distributed random variables then the resulting distribution will be the same as the one that you started with. Hence it is equally random.
However, this does not work if the shuffling is dependent on the values of the random bits in some way. If, for example, you sort the bits rather than permuting them then you won't have very good random output :-).
It would depend on how you reorder them. If you used pseudo random function to do it the results will likely be less random. If you use the true random to reorder itself it will not be more random.
One thing that people forget is the reason to use pseudo random function over some true random numbers is repeatedly and testing. If you get some unexpected results using pseudo random function will make looking at the possible problem easer.
If you have a process that needs N 'random' numbers, you can take N from the site, and use them, IN THAT ORDER, and all will be well. If you reshuffle them, you will make them less random.
If you need an ongoing supply of random numbers, then the question is the relative quality of some pseudo-random juggle of these versus what would happen if you had a true random sequence.
Since, however, linux and windows both supply real random numbers by harnessing hardware entropy, why not just use those?

Resources