text: #include <stdlib.h>
  #include <string.h>
  #include <stdio.h>
  #include <stdint.h>
  #include <float.h>
  
  #include <math.h>
  
  #include "libscrypt.h"
  
  /* Although log2 exists in GNU99 C, more portable code shouldn't use it
  * Note that this function returns a float and hence is not compatible with the
  * GNU prototype
  */
  static double scrypt_log2( uint32_t n )  
  {  
  	// log(n)/log(2) is log2.  
  	double temp;
  	/* Using the temp variable keeps splint happy */
  	temp = log(2);
  	return (log((double)n) / temp);
  }
  
  int libscrypt_mcf(uint32_t N, uint32_t r, uint32_t p, char *salt, char *hash, char *mcf)
  {
  
  
  	uint32_t params;
  	int s;
  	double t, t2, fracpart;
  
  	if(!mcf || !hash)
  		return 0;
  	/* Although larger values of r, p are valid in scrypt, this mcf format
  	* limits to 8 bits. If your number is larger, current computers will
  	* struggle
  	*/
  	if(r > (uint8_t)(-1) || p > (uint8_t)(-1))
  		return 0;
  
  
  	t = scrypt_log2(N);
  
  	/* The "whole numebr" check below is non-trivial due to precision
  	* issues, where you could printf("%d", (int)t) and find yourself
  	* looking at (expected value) -1
  	*/
  	fracpart = modf(t, &t2);
  	if(fracpart > DBL_EPSILON)
  		return 0;
  		
  	params = (r << 8) + p;
  	params += (uint32_t)t << 16;
  	
  	/* Using snprintf - not checking for overflows. We've already
  	* determined that mcf should be defined as at least SCRYPT_MCF_LEN
  	* in length 
  	*/
  	s = snprintf(mcf, SCRYPT_MCF_LEN,  SCRYPT_MCF_ID "$%06x$%s$%s", (unsigned int)params, salt, hash);
  	if (s > SCRYPT_MCF_LEN)
  		return 0;
  
  	return 1;
  }	
  