Thread: Came back to random numbers and got decent randomness

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    With a seed of zero, after a while it gets stuck in a loop of repeating 35,246 values.

    If you are feeling idle, try this:

    Code:
    static uint32_t my_rng(unsigned int x) {
       unsigned int b;
       b = x ^ (x << 3);
       b = ((~b) >> 16) & 0x7FFF;
       x = (x << 15) | b;
       return x;
    }
    It generates 2,147,483,647 unique values...

  2. #2
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,735
    Quote Originally Posted by hamster_nz View Post
    With a seed of zero, after a while it gets stuck in a loop of repeating 35,246 values.

    If you are feeling idle, try this:

    Code:
    static uint32_t my_rng(unsigned int x) {
       unsigned int b;
       b = x ^ (x << 3);
       b = ((~b) >> 16) & 0x7FFF;
       x = (x << 15) | b;
       return x;
    }
    It generates 2,147,483,647 unique values...
    If I'm able to put it under an MIT License then sure, otherwise I'll stick to searching for another method, the main reason I was looking for a method was so I can add it to my alu project, anyways I decided libpng was too complicated for my liking, I wanted a library that allows me to ........ up the file itself and just tells me what I can do with my buffer to make it compliant, so I've gone with writing my own functions, here's what I got so far:
    Code:
    int print_png_sig( FILE *out )
    {
    	char sig[8] = { 137, 80, 78, 71, 13, 10, 26, 10 };
    	size_t bytes = fwrite( sig, 1, 8, out );
    	return (bytes != 8) ? ferror(out) : 0;
    }
    
    void flip_bytes( void *buff, size_t size )
    {
    	for ( char *a = buff, *b = buff + (size-1); a < b; ++a, --b )
    	{
    		char t = *a;
    		*a = *b;
    		*b = t;
    	}
    }
    
    void* flip_words( void *buff, size_t size )
    {
    	for ( short *a = buff, *b = buff + (size-2); a < b; ++a, --b )
    	{
    		short t = *a;
    		*a = *b;
    		*b = t;
    	}
    	
    	return buff;
    }
    
    void* set_little_endian( void *buff, size_t size )
    {
    	long val = 0x12345678;
    	char *ptr = (char*)&val;
    	bool go = true;
    	
    	while ( 1 )
    	{
    		switch ( *ptr )
    		{
    		case 0x78: return buff;
    		case 0x12: flip_bytes( buff, size ); return buff;
    		case 0x34:
    			flip_words( buff, size );
    		case 0x56:
    			for ( size_t i = 0; i < size; i += 2 )
    			{
    				flip_bytes( ptr + i, 2 );
    			}
    			return buff;
    		}
    	
    		if ( !go ) return buff;
    		
    		flip_bytes( buff, size );
    		go = false;
    	}
    	
    	return buff;
    }
    
    struct png_IHDR
    {
    	size_t length : 32;
    	size_t type : 32;
    	size_t crc : 32;
    	size_t width : 32;
    	size_t height : 32;
    	size_t bit_depth : 8;
    	size_t color_type : 8;
    	size_t comparison_method : 8;
    	size_t filter_method : 8;
    	size_t interlace_method : 8;
    };
    
    #define PNG_COLOR_TYPE_GREYSCALE 0
    #define PNG_COLOR_TYPE_TRUECOLOR 2
    #define PNG_COLOR_TYPE_INDEXED 3
    #define PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA 4
    #define PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA 6
    
    #define PNG_COMPRESSION_SLIDING_WINDOW_OF_AT_MOST_0x7fff 0
    
    #define PNG_FILTER_ADAPTIVE_WITH_5_TYPES 0
    
    #define PNG_INTERLACE_NONE 0
    #define PNG_INTERLACE_ADAM7 1
    
    size_t set_png_IHDR_color_type( struct *png_IHDR chunk, size_t color_type )
    {
    	switch ( color_type )
    	{
    	case PNG_COLOR_TYPE_GREYSCALE:
    	case PNG_COLOR_TYPE_TRUECOLOR:
    	case PNG_COLOR_TYPE_INDEXED:
    	case PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA:
    	case PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA:
    		break;
    	default:
    		color_type = PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA;
    	}
    	
    	chunk->color_type = color_type;
    	return color_type;
    }
    
    size_t set_png_IHDR_bit_depth
    (
    	struct *png_IHDR chunk
    	, size_t color_type
    	, size_t bit_depth
    )
    {
    	switch ( bit_depth )
    	{
    		case 3:
    			bit_depth = 4;
    		case 1: case 2: case 4:
    			bit_depth =
    			(
    				color_type == PNG_COLOR_TYPE_GREYSCALE
    				|| color_type == PNG_COLOR_TYPE_INDEXED
    			) ? bit_depth : 8;
    			break;
    		case 6: case 7:
    			bit_depth = 8;
    		case 8: break;
    		default:
    			bit_depth = (color_type != PNG_COLOR_TYPE_INDEXED) ? 16 : 8;
    	}
    	
    	chunk->bit_depth = bit_depth;
    	return bit_depth;
    }
    
    int print_png_chunk_IHDR( FILE *out, struct png_IHDR *chunk )
    {
    	// Ignored CRC
    	int ret = 1;
    	char type[4] = { 73, 72, 68, 82 };
    	size_t leng = sizeof(png_IHDR) - 4, crc = 0;
    	size_t bytes;
    	
    	struct { size_t size, void *addr } ptrs[] =
    	{
    		{ 4, &(chunk->leng) }
    		, { 4, memcpy( &(chunk->type), type, 4 ) }
    		, { 4, &(chunk->crc) }
    		, { 0, NULL }
    	};
    	
    	set_little_endian( &leng, 4 );
    	(void)memcpy( &(chunk->leng), &leng, 4 )
    	
    	for ( int i = 0; ptrs[i].addr; ++i )
    	{
    		bytes = fwrite( ptrs[i], 1, ptrs[i].size, out );
    		
    		if ( bytes != ptrs[i].size )
    			return ferror(out);
    	}
    	
    	return ret;
    }
    Anyone see any problems?

  3. #3
    Registered User awsdert's Avatar
    Join Date
    Jan 2015
    Posts
    1,735
    While I was waiting for a response I continue my search for an example png that uses the "true colour with transparency" so I could focus on that one alone (it's not like this will be a serious library, though if anyone thinks it's better than libpng then I'll go ahead and make one, can never hurt to learn to understand the png format)

    Edit: Meant to continue after that statement, anyways, I found a guide using Go language that included some helpful info which allowed me to understand that I was misunderstanding the chunk length parameter and what I needed to do with it, so here's the improved code:
    Code:
    struct png_CHUNK
    {
    	size_t length : 32;
    	size_t type : 32;
    	size_t crc : 32;
    };
    
    struct png_IHDR
    {
    	size_t width : 32;
    	size_t height : 32;
    	size_t bit_depth : 8;
    	size_t color_type : 8;
    	size_t comparison_method : 8;
    	size_t filter_method : 8;
    	size_t interlace_method : 8;
    };
    
    #define PNG_COLOR_TYPE_GREYSCALE 0
    #define PNG_COLOR_TYPE_TRUECOLOR 2
    #define PNG_COLOR_TYPE_INDEXED 3
    #define PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA 4
    #define PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA 6
    
    #define PNG_COMPRESSION_SLIDING_WINDOW_OF_AT_MOST_0x7fff 0
    
    #define PNG_FILTER_ADAPTIVE_WITH_5_TYPES 0
    
    #define PNG_INTERLACE_NONE 0
    #define PNG_INTERLACE_ADAM7 1
    
    size_t set_png_IHDR_color_type( struct *png_IHDR data, size_t color_type )
    {
    	switch ( color_type )
    	{
    	case PNG_COLOR_TYPE_GREYSCALE:
    	case PNG_COLOR_TYPE_TRUECOLOR:
    	case PNG_COLOR_TYPE_INDEXED:
    	case PNG_COLOR_TYPE_GREYSCALE_WITH_ALPHA:
    	case PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA:
    		break;
    	default:
    		color_type = PNG_COLOR_TYPE_TRUECOLOR_WITH_ALPHA;
    	}
    	
    	data->color_type = color_type;
    	return color_type;
    }
    
    size_t set_png_IHDR_bit_depth
    (
    	struct *png_IHDR data
    	, size_t color_type
    	, size_t bit_depth
    )
    {
    	switch ( bit_depth )
    	{
    		case 3:
    			bit_depth = 4;
    		case 1: case 2: case 4:
    			bit_depth =
    			(
    				color_type == PNG_COLOR_TYPE_GREYSCALE
    				|| color_type == PNG_COLOR_TYPE_INDEXED
    			) ? bit_depth : 8;
    			break;
    		case 6: case 7:
    			bit_depth = 8;
    		case 8: break;
    		default:
    			bit_depth = (color_type != PNG_COLOR_TYPE_INDEXED) ? 16 : 8;
    	}
    	
    	data->bit_depth = bit_depth;
    	return bit_depth;
    }
    
    int print_png_chunk_IHDR( FILE *out, struct png_IHDR *data, size_t CRC )
    {
    	char type[4] = { 73, 72, 68, 82 };
    	size_t leng = sizeof(struct png_IHDR);
    	struct png_CHUNK chunk = {0}
    	
    	struct { size_t size, void *addr } ptrs[] =
    	{
    		{ 4, &(chunk.leng) }
    		, { 4, memcpy( &(chunk.type), type, 4 ) }
    		, { 4, &(data->width) }
    		, { 4, &(data->height) }
    		, { 1, &(data->bit_depth) }
    		, { 1, &(data->color_type) }
    		, { 1, &(data->comparison_method) }
    		, { 1, &(data->filter_method) }
    		, { 1, &(data->interlace_method) }
    		, { 4, &(chunk->crc) }
    		, { 0, NULL }
    	};
    	
    	set_little_endian( &leng, sizeof(size_t) );
    	(void)memcpy( &(chunk->leng), &leng, 4 );
    	
    	set_little_endian( &CRC, sizeof(size_t) );
    	(void)memcpy( &(chunk->crc), &CRC, 4 );
    	
    	for ( int i = 0; ptrs[i].addr; ++i )
    	{
    		size_t bytes = fwrite( ptrs[i].addr, 1, ptrs[i].size, out );
    		
    		if ( bytes != ptrs[i].size )
    			return ferror(out);
    	}
    	
    	return ret;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Scale back size of Numbers while maintaining proportion
    By kerrymaid in forum C Programming
    Replies: 5
    Last Post: 10-23-2011, 01:31 PM
  2. Replies: 4
    Last Post: 11-16-2004, 07:29 AM
  3. Replies: 3
    Last Post: 07-24-2002, 08:46 AM
  4. random number - replaying back.. pls help!
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 01-18-2002, 02:34 AM

Tags for this Thread