1) rand() is a very low quality random number generator. Use the Mersenne Twister instead.
2) You actually can explicitly determine equally probably the combinations and generate a single uniform, which you can map to the combination you desire. For example the code below lists the combinations. If you want to compute Combin(N, M), you have a few choices. Using factorial definitions overflows unless you are not careful or deal with very low #s. Stirling's approximation is useful as well as several other tricks. If you have overflow issues with whatever #s you need to deal with, I can write more about how to handle it... I've wrote an actuarial science / computational statistics library several years ago.
namespace {
void print(int *s, int const & k) {
for (int j=0; j<k; j++)
printf("%i ", s[j]+1);
printf("\n");
}
int diff_sum(int *s, int const & k) {
int sum=0;
for (int j=1; j<k; j++)
sum+=s[j]-s[j-1];
return sum;
}
};
void combination_list(int const & N, int const & k) {
int selection[k], reset[k-1];
selection[0]=N-k;
int i;
for (i=1; i<k; i++)
selection[i]=reset[i-1]=N-k+i;
int count=1;
print(selection, k);
int j;
while (selection[0]+diff_sum(selection, k)>=k) {
for (j=0; j<k; j++) {
if ( diff_sum(&selection[j], k-j)==k-1-j) {
selection[j]-=1;
for (i=j+1; i<k; i++)
selection[i]=reset[i-1];
count++;
print(selection, k);
}
}
}
printf("count = %i\n", count);
}