Guest User

merhash in C fixed

a guest
Jun 6th, 2014
296
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 4.25 KB | None | 0 0
  1. /*
  2.   foxhill @ news.ycombinator
  3.  
  4.   i wrote some code in javascript and it ran slow and it used all my memory and how do even?
  5.  
  6.   *sigh*
  7.  
  8.   build with
  9.  
  10.   gcc -std=c99 -Ofast -fopenmp -o mh bf.c && ./mh
  11.  
  12.   notes:
  13.   search space is 2^2108 (with all chars), but i'm searching through 64 chars.
  14.  
  15.   but my nonce counter is only 64 bits, so the search space will *never* be entirely searched.
  16.  
  17.   actually, funny story, there *isn't enough energy in the universe* to *iterate* a 2^128 counter :)
  18.   so searching the entire space is literally impossible.
  19.  
  20.   you can restrict the search space even more by changing the alphabet to lower case chars
  21.   (you'd need to make sure that the bitshifts are updated. powers of two make things a lot easier.)
  22.  
  23.   i've been lazy and hard coded things. sorry.
  24. */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <stdbool.h>
  29. #include <unistd.h>
  30. #include <string.h>
  31.  
  32. //code editor uses clang, which has no OpenMP support..
  33. #if !defined(__clang__)
  34.   #include "omp.h"
  35. #endif
  36.  
  37. //i don't usually do global persistent state, but it's needed for the exit func..
  38. uint64_t  num_searched  = 0;
  39. uint64_t  num_found     = 0;
  40. double    time_start    = 0.0;
  41.  
  42. //(yes i know zeroing them out is needless)
  43.  
  44. //print some stuff when we quit
  45. void
  46. search_finish
  47. (int sig);
  48.  
  49. //for a given string, hash it and see if it == 666
  50. bool
  51. search_hash
  52. (const char *str, size_t len);
  53.  
  54. //create a search string from a given nonce
  55. size_t
  56. search_str
  57. (uint64_t k, char buf[32]);
  58.  
  59. //actually, creating the string is needless. do generation and hash in one step
  60. //return true if hash == 666
  61. bool
  62. search_nonce
  63. (uint64_t k);
  64.  
  65. int
  66. main
  67. (int num_args, char **args)
  68. {
  69.   printf("searching.. this search never ends, so hit ^C when you're bored\n");
  70.  
  71.   const int num_threads = 4;
  72.   const int lim         = 1000000;
  73.  
  74.   signal(SIGQUIT, search_finish);
  75.   signal(SIGINT,  search_finish);
  76.  
  77.   omp_set_num_threads(num_threads);
  78.   time_start = omp_get_wtime();
  79.  
  80.   #pragma omp parallel
  81.   while (true)
  82.   {
  83.     int tn = omp_get_thread_num();
  84.  
  85.     #pragma omp for
  86.     for (int i=0; i<lim; i++)
  87.     {
  88.       uint64_t k = (num_searched*lim + i)*num_threads + tn;
  89.  
  90.       if (search_nonce(k))
  91.       {
  92.         //print out the string if it was valid
  93.         char buf[32]; memset(buf, 0, 32);
  94.         search_str(k, buf);
  95.         printf("found: %s\n", buf);
  96.  
  97.         #pragma omp critical
  98.         num_found += 1;
  99.       }
  100.     }
  101.  
  102.     #pragma omp master
  103.     num_searched += 1;
  104.   }
  105.  
  106.   return 0;
  107. }
  108.  
  109. void
  110. search_finish
  111. (int sig)
  112. {
  113.   double time_end = omp_get_wtime();
  114.  
  115.   printf("searched %lld names, found %lld devil names in %.2lfs (%.0lf Mh/s)\n",
  116.     num_searched*1000000*4,
  117.     num_found,
  118.     time_end - time_start,
  119.     (num_searched*4)/((time_end - time_start))
  120.   );
  121.  
  122.   char buf[32];memset(buf, 0, 32);
  123.   search_str(num_searched*1000000*4 + 2341, buf);
  124.  
  125.   printf("last str was: %s\n", buf);
  126.  
  127.   exit(0);
  128. }
  129.  
  130. size_t
  131. search_str
  132. (uint64_t k, char buf[32])
  133. {
  134.   static const char alphabet[] = {
  135.     "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_-"
  136.   };
  137.  
  138.   size_t p = 0;
  139.   do
  140.   {
  141.     unsigned char val = k & 63;
  142.     buf[p] = alphabet[val];
  143.     p += 1;
  144.  
  145.     k = k >> 6;
  146.   } while( k > 0 );
  147.  
  148.   return p;
  149. }
  150.  
  151. bool
  152. search_hash
  153. (const char *str, size_t len)
  154. {
  155.   /*
  156.     String.prototype.hashCode = function(){
  157.             var hash = 0, i, char;
  158.             if (this.length == 0) return hash;
  159.             for (var i = 0, l = this.length; i < l; i++) {
  160.                     char  = this.charCodeAt(i);
  161.                     hash  = ((hash<<5)-hash)+char;
  162.                     hash |= 0; // Convert to 32bit integer
  163.             }
  164.             return hash;
  165.     };
  166.   */
  167.  
  168.   uint32_t hash = 0;
  169.   for (int i=0; i<len; i++)
  170.     hash = ((hash << 5) - hash) + str[i];
  171.  
  172.   return (hash == 666);
  173. }
  174.  
  175. bool
  176. search_nonce
  177. (uint64_t k)
  178. {
  179.   static const char a[] = {
  180.     "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890_-"
  181.   };
  182.  
  183.   uint32_t h = 0;
  184.   do
  185.   {
  186.     unsigned char val = k & 63;
  187.     h = ((h << 5) - h) + a[val];
  188.     k = k >> 6;
  189.   } while( k > 0 );
  190.  
  191.   return (h == 666);
  192. }
  193.  
  194. /*
  195.   no offence intended to any parties with my opening comment :) it was a dig at JS in general.
  196.   thanks,
  197. */
Advertisement
Add Comment
Please, Sign In to add comment