Tags
C#
Math
Algorithm
Data
Error handling
Statistics
Cryptography
hack
Best practices
Architecture
CSV
DataTable
Encryption
SQL
Database
Humor
snippets
Entropy
ORM
Design Pattern
Dictionary
Jokes
Prime
Pseudorandom
Serialization
Code Generation
Compression
Coprime
Exception
Object Relational Mapping
Raspberry Pi
Reflection
Winform
Attributes
CodeDOM
Console
DataGrid
DataGridView
DataSet
Drawing
GCD
List
Mono
PropertyInfo
Sort
Static Analysis
Validation
XML
Benchmarking
Bugs
Bézier
Cellular automata
Chrome
Clipboard
Data Mapper
Designer
EULA
Extension Methods
Firefox
Games
Generics
GraphicsPath
HoneyPot
HowJSay
IComparer
IE
KeyedCollection
Luhn Algorithm
Parameter Sanitization
Query
Rogue-like
SortedDictionary
UnhandledExceptionHandler
Usercontrol
WIN32API
Showing posts with label Random. Show all posts
Showing posts with label Random. Show all posts
Tuesday, July 5, 2016
True hardware random number generator with the Raspberry PI
So, I have been getting into cryptology lately, (For my most recent projects that I may or may not have blogged about at this point, see Bloom Filter and RC4Ever on GitHub).
The other day, I had a need for a TRUE random number generator, so I was searching the web for a hardware random number generator, when I found some very pleasant information: I already own one!
As it turns out, the Raspberry Pi (A/A+/B/B+/and 2) includes a hardware based random number generator, and according to many sources, its a very good source of truly random bytes. Yay!
To get this working on your own Pi, its a breeze:
1) Install the RasPi's random number generator tools: sudo apt-get install rng-tools.
2) Add to the boot process file (/etc/modules.conf) the command to run the hwrng module: bcm2708-rng.
3) Reboot the Pi.
Now, /dev/hwrng is available for reading. Its treated like a device, and you can use the dd command to copy bytes from the device stream to a file (like examples you might have seen doing the same from /dev/random).
NOTE: /dev/hwrng is accessible by the user root only.
But we can change that! The following command gives the user level read access: sudo chmod a+r /dev/hwrng
NOTE: This setting gets reset upon every reboot.
Again, we can change that: Add the following line to /etc/rc.local file, just above the exit 0 line:
chmod a+r /dev/hwrng
And its just that easy!
Now, say if you want to generate 1 megabyte worth of random bytes to a file in /tmp, simply enter the following command into a terminal:
dd if=/dev/hwrng of=hwrng-test-data.bin bs=1024 count=1024
The bs argument specifies the size to buffer before writing to disk. You probably want to leave that at or around 1024. Its the count argument that specifies the size, or amount, of data you want to copy from /dev/hwrng, in Kilobytes. So 1024 == 1 MB, where as 1 == 1KB.
Now, its time for Step 4) Create a C# helper library to simplify the retrieval of random bytes from /dev/hwrng.
So there is two ways to approach this. One is to make a C++ library that makes native calls and then write a .NET interop library to wrap that Or, if you are like me, a little lazy, and find that ever since transitioning to C# you find it difficult to write anything in C or C++ that compiles, you may opt to just issue the above commands to the shell and just read in the resulting file from the tmp directory.
As hackey as this second option might seem, it works remarkably well and I have written a GitHub project doing just that. It consists of a library to return random bytes, and a console executable exercising said library to get random bytes. Links below!
- The PiRngWrapper GitHub Project
- The PiRngWrapperLibrary.cs wrapper code file
Labels:
Cryptography,
Math,
Random,
Raspberry Pi,
security
Wednesday, August 7, 2013
Pseudo 'random' even distribution table
In my last post, I discussed what a co-prime is and showed you to find them.
So, what's so special about relatively prime numbers? Well, then can be used to create an one-for-one distribution table that is seemingly random, but is deterministically calculated (created).
To understand what I mean, picture the face of a clock...
It has the hours 1 through 12, and if you and an hour to 12, you get 1. This can also be thought of as a single digit in a base 12 number system. Now we need a co-prime to 12. 7 is relatively prime to 12, so lets choose 7.
Starting at hour 1, if we add 7 hours, it will be 8. If we add 7 more hours, we will get 3. 7 more, 10. If we keep adding 7 hours to our clock, the hour hand will land on each of the different numbers exactly once before repeating itself, 12 steps later. Intrigued yet?
If, say, we find a co-prime to the largest number that can be represented by a byte (8-bits, 256 [also expressed as 2^8=256 or 8=Log2(256)]), we can create an array of bytes with a length of 256, containing each of the 256 different possible bytes, distributed in a seemingly random order. The discrete order, or sequence, in which each each number is visited it completely dependent on the value of the co-prime that was selected.
This table is now essentially a one-to-one, bijective mapping of one byte to another. To express this mapping to another party, say to map a stream of bytes back to their original values (decrypt), the entire table need not be exchanged, only the co-prime.
This provides a foundation for an encryption scheme who's technical requirements are similar to handling a cipher-block-chain (CBC) and its changing IV (initialization vector).
Now, it it easy to jump to the conclusion that such an encryption scheme is less secure than a CBC, but this is not necessarily the case. While this approach may be conceptually more simple, the difficulty of discovering the sequence can be made arbitrarily hard.
First of all, the number of relatively prime numbers to 256 is probably infinite. A co-prime to 256 does not have to be less than 256. Indeed, it may be several thousand time greater than 256. Additionally, any prime greater than 256 is, by definition, co-prime to 256, and likely will have a seemingly more 'random' distribution/appearance.
There is, however, a limit here. It does not have to do with the number of co-primes, but is instead limited by the number of possible sequences that can be represented by our array of 256 bytes; eventually, two different co-primes are going to map to the same unique sequence. The order matters, and we don't allow repetition to exist in our sequence. This is called a permutation without repetition, and can be expressed as 256! or 256 factorial and is instructing one to calculate the product of 256 * 255 * 254 * 253 * [...] * 6 * 5 * 4 * 3 * 2 * 1, which equals exactly this number:
857817775342842654119082271681232625157781520279485619859655650377269452553147589377440291360451408450375885342336584306157196834693696475322289288497426025679637332563368786442675207626794560187968867971521143307702077526646451464709187326100832876325702818980773671781454170250523018608495319068138257481070252817559459476987034665712738139286205234756808218860701203611083152093501947437109101726968262861606263662435022840944191408424615936000000000000000000000000000000000000000000000000000000000000000
Yeah, that's right, that number has exactly 63 zeros on the end and is 507 digits long. (As an aside, the reason there is so many zeros on the end of this number is, well for one it is highly composite, but more specifically, its prime factorization includes 2^255 and 5^63 and so 63 fives multiply with 63 of those twos to make 63 tens, and hence that many zeros.)
Above I said arbitrarily hard. So far we have only considered one table, but try and fathom the complexity of many tables. I present three different ways to use multiple tables; Nested, sequentially, and mangled.
Furthermore, the distribution tables can be discarded and replaced.
I will explain what those mean and finish this post tomorrow.
Labels:
.net,
Algorithm,
C#,
Coprime,
Cryptography,
csharp,
Data,
Distributed Table,
Encryption,
Entropy,
GCD,
Math,
Pseudorandom,
Random,
security,
Statistics
Tuesday, July 9, 2013
Procedural generation of cave-like maps for rogue-like games
This post is about procedural content generation of cave-like dungeons/maps for rogue-like games using what is known as the Cellular Automata method.
To understand what I mean by cellular automata method, imagine Conway's Game of Life. Many algorithms use what is called the '4-5 method', which means a tile will become a wall if it is a wall and 4 or more of its nine neighbors are walls, or if it is not a wall and 5 or more neighbors are walls. I start by filling the map randomly with walls or space, then visit each x/y position iteratively and apply the 4-5 rule. Usually this is preceded with 'seeding' the map by randomly filling each cell of the map with a wall or space, based on some weight (say, 40% of the time it chooses to place a wall). Then the automata step is applied multiple times over the entire map, precipitating walls and subsequently smoothing them. About 3 rounds is all that is required, with about 4-5 rounds being pretty typical amongst most implementations. Perhaps a picture of the the output will help you understand what I mean.
Using the automata-based method for procedural generation of levels will produce something similar to this:
Sure the dungeon generation by linking rooms approach has its place, but I really like the 'natural' look to the automata inspired method. I first originally discovered this technique on the website called Roguebasin. It is a great resource for information concerning the different problems involved with programming a rogue-like game, such as Nethack or Angband.
One of the major problems developers run into while employing this technique is the formation of isolated caves. Instead of one big cave-like room, you may get section of the map that is inaccessible without digging through walls. Isolated caves can trap key items or (worse) stairs leading to the next level, preventing further progress in the game. I have seen many different approaches proposed to solve this problem. Some suggestions I've seen include: 1) Discarding maps that have isolated caves, filling in the isolated sections, or finely tweaking the variables/rules to reduce occurrences of such maps. None of these are ideal (in my mind), and most require a way to detect isolated sections, which is another non-trivial problem in itself.
Despite this, I consider the problem solved because I have discovered a solution that is dead simple and almost** never fail because of the rules of the automata generation itself dictate such. I call my method 'Horizontal Blanking' because you can probably guess how it works now just from hearing the name. This step comes after the random filling of the map (initialization), but before the cellular automata iterations. After the map is 'seeded' with a random fill of walls, a horizontal strip in the middle of of the map is cleared of all walls. The horizontal strip is about 3 or 4 block tall (depending on rules). Clearing a horizontal strip of sufficient width will prevent a continuous vertical wall from being created and forming isolated caves in your maps. After horizontal blanking, you can begin applying the cellular automata method to your map.
** I say 'almost' because although it it not possible to get whole rooms that are disconnected from each other, it is possible to get tiny squares of blank space in the northern or southern walls that consist of about 4-5 blocks in total area. Often, these little holes will resolve themselves during the rounds of automata rules, but there still exists the possibility that one may persist. My answer to this edge case would be to use some rules around the placement of stairwells (and other must-find items) dictating that such objects must have a 2-3 block radius clear of walls to be placed.
See below for the code that produced the above screenshot, or click here to download the entire project with source code that you can compile yourself.
public class MapHandler
{
Random rand = new Random();
public int[,] Map;
public int MapWidth { get; set; }
public int MapHeight { get; set; }
public int PercentAreWalls { get; set; }
public MapHandler()
{
MapWidth = 40;
MapHeight = 21;
PercentAreWalls = 40;
RandomFillMap();
}
public void MakeCaverns()
{
// By initilizing column in the outter loop, its only created ONCE
for(int column=0, row=0; row <= MapHeight-1; row++)
{
for(column = 0; column <= MapWidth-1; column++)
{
Map[column,row] = PlaceWallLogic(column,row);
}
}
}
public int PlaceWallLogic(int x,int y)
{
int numWalls = GetAdjacentWalls(x,y,1,1);
if(Map[x,y]==1)
{
if( numWalls >= 4 )
{
return 1;
}
return 0;
}
else
{
if(numWalls>=5)
{
return 1;
}
}
return 0;
}
public int GetAdjacentWalls(int x,int y,int scopeX,int scopeY)
{
int startX = x - scopeX;
int startY = y - scopeY;
int endX = x + scopeX;
int endY = y + scopeY;
int iX = startX;
int iY = startY;
int wallCounter = 0;
for(iY = startY; iY <= endY; iY++) {
for(iX = startX; iX <= endX; iX++)
{
if(!(iX==x && iY==y))
{
if(IsWall(iX,iY))
{
wallCounter += 1;
}
}
}
}
return wallCounter;
}
bool IsWall(int x,int y)
{
// Consider out-of-bound a wall
if( IsOutOfBounds(x,y) )
{
return true;
}
if( Map[x,y]==1 )
{
return true;
}
if( Map[x,y]==0 )
{
return false;
}
return false;
}
bool IsOutOfBounds(int x, int y)
{
if( x<0 data-blogger-escaped-else="" data-blogger-escaped-if="" data-blogger-escaped-return="" data-blogger-escaped-true="" data-blogger-escaped-x="" data-blogger-escaped-y="">MapWidth-1 || y>MapHeight-1 )
{
return true;
}
return false;
}
Above is the main core of the logic.Here is the rest of the program, such as filling, printing and blanking:
public void PrintMap()
{
Console.Clear();
Console.Write(MapToString());
}
string MapToString()
{
string returnString = string.Join(" ", // Seperator between each element
"Width:",
MapWidth.ToString(),
"\tHeight:",
MapHeight.ToString(),
"\t% Walls:",
PercentAreWalls.ToString(),
Environment.NewLine
);
List<string> mapSymbols = new List();
mapSymbols.Add(".");
mapSymbols.Add("#");
mapSymbols.Add("+");
for(int column=0,row=0; row < MapHeight; row++ ) {
for( column = 0; column < MapWidth; column++ )
{
returnString += mapSymbols[Map[column,row]];
}
returnString += Environment.NewLine;
}
return returnString;
}
public void BlankMap()
{
for(int column=0,row=0; row < MapHeight; row++) {
for(column = 0; column < MapWidth; column++) {
Map[column,row] = 0;
}
}
}
public void RandomFillMap()
{
// New, empty map
Map = new int[MapWidth,MapHeight];
int mapMiddle = 0; // Temp variable
for(int column=0,row=0; row < MapHeight; row++) {
for(column = 0; column < MapWidth; column++)
{
// If coordinants lie on the edge of the map
// (creates a border)
if(column == 0)
{
Map[column,row] = 1;
}
else if (row == 0)
{
Map[column,row] = 1;
}
else if (column == MapWidth-1)
{
Map[column,row] = 1;
}
else if (row == MapHeight-1)
{
Map[column,row] = 1;
}
// Else, fill with a wall a random percent of the time
else
{
mapMiddle = (MapHeight / 2);
if(row == mapMiddle)
{
Map[column,row] = 0;
}
else
{
Map[column,row] = RandomPercent(PercentAreWalls);
}
}
}
}
}
int RandomPercent(int percent)
{
if(percent>=rand.Next(1,101))
{
return 1;
}
return 0;
}
public MapHandler(int mapWidth, int mapHeight, int[,] map, int percentWalls=40)
{
this.MapWidth = mapWidth;
this.MapHeight = mapHeight;
this.PercentAreWalls = percentWalls;
this.Map = new int[this.MapWidth,this.MapHeight];
this.Map = map;
}
}
And of course, the main function:
public static void Main(string[] args)
{
char key = new Char();
MapHandler Map = new MapHandler();
string instructions =
"[Q]uit [N]ew [+][-]Percent walls [R]andom [B]lank" + Environment.NewLine +
"Press any other key to smooth/step";
Map.MakeCaverns();
Map.PrintMap();
Console.WriteLine(instructions);
key = Char.ToUpper(Console.ReadKey(true).KeyChar);
while(!key.Equals('Q'))
{
if(key.Equals('+')) {
Map.PercentAreWalls+=1;
Map.RandomFillMap();
Map.MakeCaverns();
Map.PrintMap();
} else if(key.Equals('-')) {
Map.PercentAreWalls-=1;
Map.RandomFillMap();
Map.MakeCaverns();
Map.PrintMap();
} else if(key.Equals('R')) {
Map.RandomFillMap();
Map.PrintMap();
} else if(key.Equals('N')) {
Map.RandomFillMap();
Map.MakeCaverns();
Map.PrintMap();
} else if(key.Equals('B')) {
Map.BlankMap();
Map.PrintMap();
} else if(key.Equals('D')) {
// I set a breakpoint here...
} else {
Map.MakeCaverns();
Map.PrintMap();
}
Console.WriteLine(instructions);
key = Char.ToUpper(Console.ReadKey(true).KeyChar);
}
Console.Clear();
Console.Write(" Thank you for playing!");
Console.ReadKey(true);
}
See also: Roguebasin - Cellular Automata Method for Generating Random Cave-Like Levels
Labels:
.net,
Algorithm,
C#,
Cellular automata,
Class,
Cool,
csharp,
Games,
hack,
Math,
Procedural content generation,
Random,
Rogue-like,
RPG,
Statistics
Thursday, June 27, 2013
Fake/Random Identity Generator
Inspiration
During my research on RSA cryptography and the importance of a truly random number for having a large key-space, I stumbled on to FakeNameGenerator.com. I thought the concept could be really useful for certain applications and could easily envision how to implement it in C#, and make it extensible/customizable.
Take a look at these:
<?xml version="1.0" standalone="yes"?>
<DocumentElement>
<Order>
<Date>3/18/2005</Date>
<TrackingNumber>1Z 8A8 238 01 9398 182 1</TrackingNumber>
<FirstName>Keaton </FirstName>
<LastName>Day</LastName>
<StreetAddress>4828 Cherry St.</StreetAddress>
<City>Nanticoke</City>
<State>SC</State>
<Zip>89130</Zip>
<Email>HaleHale8026@mail.com</Email>
<Phone>425-765-4520</Phone>
</Order>
<Payroll>
<PhoneNumber>971-258-5703</PhoneNumber>
<AltPhoneNumber>501-769-1331</AltPhoneNumber>
<FirstName>Xyla </FirstName>
<LastName>Hoover</LastName>
<EmployeeID>499</EmployeeID>
<HireDate>5/28/2011</HireDate>
<Birthdate>5/28/1990</Birthdate>
<SSN>520-52-4275</SSN>
<AccountNumber>5696618825</AccountNumber>
<RoutingNumber>575159859</RoutingNumber>
<Address>8348 Court Ave.</Address>
<City>Pittsburgh,</City>
<State>PA.</State>
<Zip>15201</Zip>
</Payroll>
CREATE TABLE ReservationData (
`id` mediumint(8) unsigned NOT NULL auto_increment,
`UniqueID` MEDIUMINT default NULL,
`TripDate` varchar(50) default NULL,
`FirstName` varchar(255) default NULL,
`LastName` varchar(255) default NULL,
`Phone` varchar(100) default NULL,
`AltPhone` varchar(100) default NULL,
`Email` varchar(255) default NULL,
`StreetAddress` varchar(255) default NULL,
`City` varchar(50) default NULL,
`State` varchar(50) default NULL,
`Zip` varchar(10) default NULL,
`Country` varchar(255) default NULL,
`DayOfYear` varchar(50) default NULL,
`TotalCost` varchar(50) default NULL,
`Balance` varchar(10) default NULL,
`CCard` varchar(18) default NULL,
`Expires` varchar(5) default NULL,
`CVC2` varchar(3) default NULL,
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1;
This would make great honey for a honey pot; just fill an SQL database with this random, realistic looking data, serve and log any and all attempts to access, query or dump the database. This can be done on a VM and you have a easily deployed, high interaction honeypot!
Aside from being able to see their IP address, I think the most useful data that can be attained is their behavior; what injection attacks are they using to drop the database? Write rules to prevent your honey against trivial attempts such as the ' AND 1=(SELECT attacks and see what they come up with next. Rule writing is inherently a cat-and-mouse game, honeypots like this clearly give the white-hats the upper hand.
Implementation
A quick, fast and dirty solution is to simply read a random line from a text file (i.e. Name_First.txt and Address_Street.txt).
This way, you can choose from names that are common, or customize your list to for different nationalities.
One could read the whole file in to a string, Parse() it into an array of strings, then randomly select an index, but this would be unacceptable for very large files. Instead, we can set the file pointer to a random position that is less than its size, roll back to the last new line and call ReadLine.
public string ReturnRandomLine(string FileName)
{
string sReturn = string.Empty;
using(FileStream myFile = new FileStream(FileName,FileMode.Open,FileAccess.Read))
{
using(StreamReader myStream = new StreamReader(myFile))
{
// Seek file stream pointer to a rand position...
myStream.BaseStream.Seek(rand.Next(1,myFile.Length),SeekOrigin.Begin);
// Read the rest of that line.
myStream.ReadLine();
// Return the next, full line...
sReturn = myStream.ReadLine();
}
}
// If our random file position was too close to the end of the file, it will return an empty string
// I avoided a while loop in the case that the file is empty or contains only one line
if(System.String.IsNullOrWhiteSpace(sReturn)) {
sReturn = ReturnRandomLine(FileName);
}
return sReturn;
}
Example use:
public string GenerateFistName()
{
return ReturnRandomLine("Name_First.txt") + " ";
}
public string GenerateLastName()
{
return ReturnRandomLine("Name_Last.txt");
}
public string GenerateFullName()
{
return GenerateFistName() + GenerateLastName();
}
public string GenerateGender()
{
if(ReturnPercent(84)) {
return "Male";
} else {
return "Female";
}
}
public string GenerateStreetNumber()
{
return rand.Next(1,9999).ToString();
}
public string GenerateStreetName()
{
return ReturnRandomLine("Address_Street.txt");
}
One limitation is where the data is relational, such as in the case of generating a random zip code along with the city and state that it exists in.
A quick work-around would be CityZipState.txt
Other types of data that can be generated that would not make sense to put in a text file:
public bool ReturnPercent(int Percent) // Return true Percent times out of 100, randomly
{
int iTemp = rand.Next(1,101);
if(iTemp<=Percent) {
return true;
} else {
return false;
}
}
public string GenerateDate(int YearFrom,int YearTo)
{
int Month = rand.Next(1,13);
int Day = rand.Next(1,32);
int Year = GenerateYear(YearFrom,YearTo);
return Month.ToString() + "/" + Day.ToString() + "/" + Year.ToString();
}
public string GenerateYear(int YearFrom,int YearTo)
{
return rand.Next(YearFrom,YearTo+1).ToString();
}
public string GeneratePhoneNumber()
{
return GeneratePhoneNumber(ReturnRandomLine("PhoneNumber_Prefix.txt"));
}
public string GeneratePhoneNumber(string Prefix)
{
int iThree = rand.Next(192,999);
int iFour = rand.Next(1000,9999);
return Prefix + iThree.ToString() + "-" + iFour.ToString();
}
public string GenerateSSN()
{
int iThree = rand.Next(132,921);
int iTwo = rand.Next(12,83);
int iFour = rand.Next(1423,9211);
return iThree.ToString() + "-" + iTwo.ToString() + "-" + iFour.ToString();
}
Obviously, these methods can be improved to conform to the standards of a real social security number, national identification number, credit card number, ect...
public string GenerateCCNum()
{
string sCCNum = string.Empty;
byte[] bCCNum = {0};
rand.NextBytes(bCCNum);
// generate random 16 digit number
int iTemp1 = rand.Next(10000000,99999999);
int iTemp2 = rand.Next(10000000,99999999);
string sTemp = iTemp1.ToString() + iTemp2.ToString();
// while loop?
while(!IsValidNumber(sTemp))
{
iTemp1 = rand.Next(10000000,99999999);
iTemp2 = rand.Next(10000000,99999999);
sTemp = iTemp1.ToString() + iTemp2.ToString();
}
sCCNum = sTemp;
return sCCNum;
}
The implementation of IsValidNumber() is left as an exercise for the reader.
The serialization of your data is a trivial matter. Please see my post on a XML Serializable Dictionary, Tuple, and Object for the code to serialize an object (such as a list, or a class).
Subscribe to:
Posts (Atom)