//  SHUFFLE.C
//  Shuffles chars
//  Based on algorithm given in Knuth, Volume 2, p.125.

//  These functions assume that the RNG has been initialized
//  or that random numbers from the current stream are being used.

unsigned char rnd(void);
unsigned char pm(void);

/*-------------------------------*/
void shuffle(unsigned char *buffer,
             unsigned int num_bytes)
{
unsigned int j, m, k=0;
unsigned char c;  

if ( num_bytes < 2 )
    return;
  
j = num_bytes - 1;
while ( j > 0 )
    {
    //  m = m_a[k++] = ( (rnd()+256*pm())%(j+1) );
    m = ( (rnd()+256*pm())%(j+1) );  //  0 <= m <= j
    c = buffer[j];
    buffer[j] = buffer[m];
    buffer[m] = c;
    j--;
    }
}

//  This uses a buffer m_a to hold num_bytes random numbers
//  which are then used in reverse order to do the unshuffle.
/*-------------------------------*/
void unshuffle(unsigned char *buffer,
               unsigned int *m_a,
               unsigned int num_bytes)
{
unsigned int j, k=0, m;
unsigned char c;      

if ( num_bytes < 2 )
    return;

j = num_bytes - 1;
while ( j > 0 )
    {
    m_a[k++] = ( (rnd()+256*pm())%(j+1) );  
    j--;
    }

j = 1;
while ( j < num_bytes )
    {
    m = m_a[--k];
    c = buffer[j];
    buffer[j] = buffer[m];
    buffer[m] = c;
    j++;
    }
}