scripts

misc scripts and tools
git clone git://git.2f30.org/scripts
Log | Files | Refs

scramble.c (4963B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 
      4 #define MAXCHUNK (2048*1024)
      5 
      6 static unsigned int seed;
      7 
      8 void my_srand(unsigned int n)
      9 {
     10   seed = n & 0xffff;
     11 }
     12 
     13 unsigned int my_rand()
     14 {
     15   seed = (seed * 2109 + 9273) & 0x7fff;
     16   return (seed + 0xc000) & 0xffff;
     17 }
     18 
     19 void load(FILE *fh, unsigned char *ptr, unsigned long sz)
     20 {
     21   if(fread(ptr, 1, sz, fh) != sz)
     22     {
     23       fprintf(stderr, "Read error!\n");
     24       exit(1);
     25     }
     26 }
     27 
     28 void load_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
     29 {
     30   static int idx[MAXCHUNK/32];
     31   int i;
     32 
     33   /* Convert chunk size to number of slices */
     34   sz /= 32;
     35 
     36   /* Initialize index table with unity,
     37      so that each slice gets loaded exactly once */
     38   for(i = 0; i < sz; i++)
     39     idx[i] = i;
     40 
     41   for(i = sz-1; i >= 0; --i)
     42     {
     43       /* Select a replacement index */
     44       int x = (my_rand() * i) >> 16;
     45 
     46       /* Swap */
     47       int tmp = idx[i];
     48       idx[i] = idx[x];
     49       idx[x] = tmp;
     50 
     51       /* Load resulting slice */
     52       load(fh, ptr+32*idx[i], 32);
     53     }
     54 }
     55 
     56 void load_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
     57 {
     58   unsigned long chunksz;
     59 
     60   my_srand(filesz);
     61 
     62   /* Descramble 2 meg blocks for as long as possible, then
     63      gradually reduce the window down to 32 bytes (1 slice) */
     64   for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
     65     while(filesz >= chunksz)
     66       {
     67 	load_chunk(fh, ptr, chunksz);
     68 	filesz -= chunksz;
     69 	ptr += chunksz;
     70       }
     71 
     72   /* Load final incomplete slice */
     73   if(filesz)
     74     load(fh, ptr, filesz);
     75 }
     76 
     77 void read_file(char *filename, unsigned char **ptr, unsigned long *sz)
     78 {
     79   FILE *fh = fopen(filename, "rb");
     80   if(fh == NULL)
     81     {
     82       fprintf(stderr, "Can't open \"%s\".\n", filename);
     83       exit(1);
     84     }
     85   if(fseek(fh, 0, SEEK_END)<0)
     86     {
     87       fprintf(stderr, "Seek error.\n");
     88       exit(1);
     89     }
     90   *sz = ftell(fh);
     91   *ptr = malloc(*sz);
     92   if( *ptr == NULL )
     93     {
     94       fprintf(stderr, "Out of memory.\n");
     95       exit(1);
     96     }
     97   if(fseek(fh, 0, SEEK_SET)<0)
     98     {
     99       fprintf(stderr, "Seek error.\n");
    100       exit(1);
    101     }
    102   load_file(fh, *ptr, *sz);
    103   fclose(fh);
    104 }
    105 
    106 void save(FILE *fh, unsigned char *ptr, unsigned long sz)
    107 {
    108   if(fwrite(ptr, 1, sz, fh) != sz)
    109     {
    110       fprintf(stderr, "Write error!\n");
    111       exit(1);
    112     }
    113 }
    114 
    115 void save_chunk(FILE *fh, unsigned char *ptr, unsigned long sz)
    116 {
    117   static int idx[MAXCHUNK/32];
    118   int i;
    119 
    120   /* Convert chunk size to number of slices */
    121   sz /= 32;
    122 
    123   /* Initialize index table with unity,
    124      so that each slice gets saved exactly once */
    125   for(i = 0; i < sz; i++)
    126     idx[i] = i;
    127 
    128   for(i = sz-1; i >= 0; --i)
    129     {
    130       /* Select a replacement index */
    131       int x = (my_rand() * i) >> 16;
    132 
    133       /* Swap */
    134       int tmp = idx[i];
    135       idx[i] = idx[x];
    136       idx[x] = tmp;
    137 
    138       /* Save resulting slice */
    139       save(fh, ptr+32*idx[i], 32);
    140     }
    141 }
    142 
    143 void save_file(FILE *fh, unsigned char *ptr, unsigned long filesz)
    144 {
    145   unsigned long chunksz;
    146 
    147   my_srand(filesz);
    148 
    149   /* Descramble 2 meg blocks for as long as possible, then
    150      gradually reduce the window down to 32 bytes (1 slice) */
    151   for(chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
    152     while(filesz >= chunksz)
    153       {
    154 	save_chunk(fh, ptr, chunksz);
    155 	filesz -= chunksz;
    156 	ptr += chunksz;
    157       }
    158 
    159   /* Save final incomplete slice */
    160   if(filesz)
    161     save(fh, ptr, filesz);
    162 }
    163 
    164 void write_file(char *filename, unsigned char *ptr, unsigned long sz)
    165 {
    166   FILE *fh = fopen(filename, "wb");
    167   if(fh == NULL)
    168     {
    169       fprintf(stderr, "Can't open \"%s\".\n", filename);
    170       exit(1);
    171     }
    172   save_file(fh, ptr, sz);
    173   fclose(fh);
    174 }
    175 
    176 void descramble(char *src, char *dst)
    177 {
    178   unsigned char *ptr = NULL;
    179   unsigned long sz = 0;
    180   FILE *fh;
    181 
    182   read_file(src, &ptr, &sz);
    183 
    184   fh = fopen(dst, "wb");
    185   if(fh == NULL)
    186     {
    187       fprintf(stderr, "Can't open \"%s\".\n", dst);
    188       exit(1);
    189     }
    190   if( fwrite(ptr, 1, sz, fh) != sz )
    191     {
    192       fprintf(stderr, "Write error.\n");
    193       exit(1);
    194     }
    195   fclose(fh);
    196   free(ptr);
    197 }
    198 
    199 void scramble(char *src, char *dst)
    200 {
    201   unsigned char *ptr = NULL;
    202   unsigned long sz = 0;
    203   FILE *fh;
    204 
    205   fh = fopen(src, "rb");
    206   if(fh == NULL)
    207     {
    208       fprintf(stderr, "Can't open \"%s\".\n", src);
    209       exit(1);
    210     }
    211   if(fseek(fh, 0, SEEK_END)<0)
    212     {
    213       fprintf(stderr, "Seek error.\n");
    214       exit(1);
    215     }
    216   sz = ftell(fh);
    217   ptr = malloc(sz);
    218   if( ptr == NULL )
    219     {
    220       fprintf(stderr, "Out of memory.\n");
    221       exit(1);
    222     }
    223   if(fseek(fh, 0, SEEK_SET)<0)
    224     {
    225       fprintf(stderr, "Seek error.\n");
    226       exit(1);
    227     }
    228   if( fread(ptr, 1, sz, fh) != sz )
    229     {
    230       fprintf(stderr, "Read error.\n");
    231       exit(1);
    232     }
    233   fclose(fh);
    234 
    235   write_file(dst, ptr, sz);
    236 
    237   free(ptr);
    238 }
    239 
    240 int main(int argc, char *argv[])
    241 {
    242   int opt = 0;
    243 
    244   if(argc > 1 && !strcmp(argv[1], "-d"))
    245     opt ++;
    246 
    247   if(argc != 3+opt)
    248     {
    249       fprintf(stderr, "Usage: %s [-d] from to\n", argv[0]);
    250       exit(1);
    251     }
    252   
    253   if(opt)
    254     descramble(argv[2], argv[3]);
    255   else
    256     scramble(argv[1], argv[2]);
    257 
    258   return 0;
    259 }