1 /*
2 *========================================================================
3 * See copyright in copyright.h and the accompanying file COPYING
4 *========================================================================
5 */
6
7 #include <dieharder/libdieharder.h>
8
9 /*
10 * This should be the only tool we use to access bit substrings
11 * from now on. Note that we write our own bitstring access tools
12 * instead of using ldap's LBER (Basic Encoding Rules) library call
13 * to both retain control and because it would introduce a slightly
14 * exotic dependency in the resulting application.
15 *
16 * bstring is a pointer to the uint string to be parsed. It is a uint
17 * pointer to make it easy to pass arbitrary strings which will generally
18 * be e.g. unsigned ints in dieharder but might be other data types
19 * in other applications (might as well make this semi-portable while I'm
20 * writing it at all). bslen is the length of bitstring in uints. blen is
21 * the length of the bitstring to be returned (as an unsigned int) and has
22 * to be less than the length, in bits, of bitstring. Finally, boffset
23 * is the bit index of the point in the bitstring from which the result
24 * will be returned.
25 *
26 * The only other thing that has to be defined is the direction from which
27 * the bit offset and bit length are counted. We will make the
28 * LEAST significant bit offset 0, and take the string from the direction
29 * of increasing signicance. Examples:
30 *
31 * bitstring: 10010110, length 1 (byte, char).
32 * for offset 0, length 4 this should return: 0110
33 * offset 1, length 4: 1011
34 * offset 5, length 4: 0100 (note periodic wraparound)
35 * offset 6, length 4: 1010 (ditto)
36 *
37 * where of course the strings are actually returned as e.g.
38 * 00000000000000000000000000000110 (unsigned int).
39 */
get_bit_ntuple(unsigned int * bitstring,unsigned int bslen,unsigned int blen,unsigned int boffset)40 unsigned int get_bit_ntuple(unsigned int *bitstring,unsigned int bslen,unsigned int blen,unsigned int boffset)
41 {
42
43 unsigned int b,rlen;
44 int ioffset;
45 unsigned int result,carry,nmask;
46
47 /*
48 * Some tests for failure or out of bounds. 8*blen has to be less than
49 * sizeof(uint).
50 */
51 if(blen > 8*sizeof(unsigned int)) blen = 8*sizeof(unsigned int);
52 /*
53 * Now that blen is sane, we can make a mask for the eventual return
54 * value of length blen.
55 */
56 nmask = 1;
57 /* dumpbits(&nmask,32); */
58 for(b=0;b<blen-1;b++) {
59 nmask = nmask <<1;
60 nmask++;
61 /* dumpbits(&nmask,32); */
62 }
63 /* dumpbits(&nmask,32); */
64
65 if(verbose == D_BITS || verbose == D_ALL){
66 printf("# get_bit_ntuple(): bslen = %u, blen = %u, boffset = %u\n",bslen,blen,boffset);
67 printf("# get_bit_ntuple(): bitstring (uint) = %u\n",*bitstring);
68 printf("# get_bit_ntuple(): bitstring = ");
69 dumpbits(&bitstring[0],32);
70 printf("# get_bit_ntuple(): nmask = ");
71 dumpbits(&nmask,32);
72 }
73
74 /*
75 * This is the index of bitstring[] containing the first bit to
76 * be returned, for example if boffset is 30, rmax_bits is 24,
77 * and bslen (the length of the uint bitstring) is 4 (indices
78 * run from 0-3) then ioffset is 4 - 1 -1 = 2 and the 30th bit
79 * from the RIGHT is to be found in bitstring[2]. Put this uint
80 * into result to work on further.
81 */
82 ioffset = bslen - (unsigned int) boffset/rmax_bits - 1;
83 result = bitstring[ioffset];
84 if(verbose == D_BITS || verbose == D_ALL){
85 printf("bitstring[%d] = %u\n",ioffset,result);
86 printf("Initial result = ");
87 dumpbits(&result,32);
88 }
89 /*
90 * Now, WHICH bit in result is the boffset relative to ITS
91 * rightmost bit? We have to find the modulus boffset%rmax_bits.
92 * For example 30%24 = 6, so in the continuing example it would
93 * be bit 6 in result.
94 */
95 boffset = boffset%rmax_bits;
96 if(verbose == D_BITS || verbose == D_ALL){
97 printf("Shifting to bit offset %u\n",boffset);
98 }
99
100 /*
101 * Now for the easy part. We shift right boffset bits.
102 */
103 for(b=0;b<boffset;b++) result = result >> 1;
104 if(verbose == D_BITS || verbose == D_ALL){
105 printf("Shifted result = ");
106 dumpbits(&result,32);
107 }
108
109 /*
110 * rlen is the cumulated length of result. Initially, it is set to
111 * rmax_bits - boffset, the number of bits result can now contribute from
112 * boffset. We now have to loop, adding bits from uints up the list
113 * (cyclic) until we get enough to return blen. Note that we have to
114 * loop because (for example) blen = 32, rmax_bits = 16, boffset = 30
115 * would start in bitstring[2] and get 2 bits (30 and 31), get all 16 bits
116 * from bitstring[1], and still need 12 bits of bitstring[0] to return.
117 */
118 rlen = rmax_bits - boffset;
119 if(verbose == D_BITS || verbose == D_ALL){
120 printf("Cumulated %u signifcant bits\n",rlen);
121 }
122
123 while(blen > rlen){
124 /*
125 * If we get here, we have to use either bitstring[ioffset-1] or
126 * bitstring[bslen-1], shifted and filled into result starting
127 * at the correct slot. Put this into carry to work on.
128 */
129 ioffset--;
130 if(ioffset < 0) ioffset = bslen-1;
131 carry = bitstring[ioffset];
132 if(verbose == D_BITS || verbose == D_ALL){
133 printf("bitstring[%d] = %u\n",ioffset,carry);
134 printf("Next carry = ");
135 dumpbits(&carry,32);
136 }
137
138 /*
139 * This is tricky! Shift carry left until the first bit lines
140 * up with the first empty bit in result, which we'll hope is
141 * the current rlen bit.
142 */
143 for(b=0;b<rlen;b++){
144 carry = carry << 1;
145 }
146 if(verbose == D_BITS || verbose == D_ALL){
147 printf("Shifted carry = ");
148 dumpbits(&carry,32);
149 }
150
151 /*
152 * Now we simply add result and carry AND increment rlen by
153 * rmax_bit (since this is the exact number of bits it adds
154 * to rlen).
155 */
156 result += carry;
157 rlen += rmax_bits;
158 if(verbose == D_BITS || verbose == D_ALL){
159 printf("Cumulated %u signifcant bits\n",rlen);
160 printf("result+carry = ");
161 dumpbits(&result,32);
162 }
163 }
164
165 result = result & nmask;
166 if(verbose == D_BITS || verbose == D_ALL){
167 printf("Returning Result = ");
168 dumpbits(&result,32);
169 printf("==========================================================\n");
170 }
171 return(result);
172
173 }
174
175 /*
176 * dumpbits only can dump <= 8*sizeof(unsigned int) bits at a time.
177 */
dumpbits(unsigned int * data,unsigned int nbits)178 void dumpbits(unsigned int *data, unsigned int nbits)
179 {
180
181 unsigned int i,j;
182 unsigned int mask;
183
184 if(nbits > 8*sizeof(unsigned int)) {
185 nbits = 8*sizeof(unsigned int);
186 }
187
188 mask = (unsigned int)pow(2,nbits-1);
189 for(i=0;i<nbits;i++){
190 if(verbose == -1){
191 printf("\nmask = %u = %04x :",mask,mask);
192 }
193 j = (mask & *data)?1:0;
194 printf("%1u",j);
195 mask = mask >> 1;
196 }
197
198 }
199
200 /*
201 * dumpbitwin is being rewritten to dump the rightmost nbits
202 * from a uint, only.
203 */
dumpbitwin(unsigned int data,unsigned int nbits)204 void dumpbitwin(unsigned int data, unsigned int nbits)
205 {
206
207 while (nbits > 0){
208 printf("%d",(data >> (nbits-1)) & 1);
209 nbits--;
210 }
211
212 }
213
dumpuintbits(unsigned int * data,unsigned int nuints)214 void dumpuintbits(unsigned int *data, unsigned int nuints)
215 {
216
217 unsigned int i;
218 printf("|");
219 for(i=0;i<nuints;i++) {
220 dumpbits(&data[i],sizeof(unsigned int)*CHAR_BIT);
221 printf("|");
222 }
223
224 }
225
cycle(unsigned int * data,unsigned int nbits)226 void cycle(unsigned int *data, unsigned int nbits)
227 {
228 unsigned int i;
229 unsigned int result,rbit,lmask,rmask;
230 /*
231 * We need two masks. One is a mask of all the significant bits
232 * in the rng, which may be as few as 24 and can easily be only
233 * 31.
234 *
235 * The other is lmask, with a single bit in the position of the
236 * leftmost significant bit. We can make them both at once.
237 */
238 rmask = 1;
239 lmask = 1;
240 for(i=0;i<nbits-1;i++) {
241 rmask = rmask << 1;
242 rmask++;
243 lmask = lmask << 1;
244 }
245 if(verbose){
246 printf("%u bit rmask = ",nbits);
247 dumpbits(&rmask,32);
248 printf("%u bit lmask = ",nbits);
249 dumpbits(&lmask,32);
250 }
251 /*
252 * Next, we create mask the int being bit cycled into an internal
253 * register.
254 */
255 result = *data & rmask;
256 if(verbose){
257 printf("Original int: ");
258 dumpbits(data,32);
259 printf(" Masked int: ");
260 dumpbits(&result,32);
261 }
262 rbit = 1 & result;
263 result = result >> 1;
264 result += rbit*lmask;
265 *data = result;
266 if(verbose){
267 printf(" Rotated int: ");
268 dumpbits(data,32);
269 }
270
271 }
272
273 /*
274 * This is still a good idea, but we have to modify it so that it ONLY
275 * gets VALID bits by their absolute index.
276 */
get_bit(unsigned int * rand_uint,unsigned int n)277 int get_bit(unsigned int *rand_uint, unsigned int n)
278 {
279
280 unsigned int index,offset,mask;
281
282 /*
283 * This routine is designed to get the nth VALID bit of an input uint
284 * *rand_int. The indexing is a bit tricky. index tells us which vector
285 * element contains the bit being sought:
286 */
287 index = (int) (n/rmax_bits);
288
289 /*
290 * Then we have to compute the offset of the bit desired, starting from
291 * the first significant/valid bit in the unsigned int.
292 */
293 offset = (8*sizeof(unsigned int) - rmax_bits) + n%rmax_bits;
294 mask = (int)pow(2,8*sizeof(unsigned int) - 1);
295 mask = mask>>offset;
296 if(mask & rand_uint[index]){
297 return(1);
298 } else {
299 return(0);
300 }
301
302 }
303
get_int_bit(unsigned int i,unsigned int n)304 int get_int_bit(unsigned int i, unsigned int n)
305 {
306
307 unsigned int mask;
308
309 /*
310 * This routine gets the nth bit of the unsigned int i. It does very
311 * limited checking to ensure that n is in the range 0-sizeof(uint)
312 * Note
313 */
314 if(n < 0 || n > 8*sizeof(unsigned int)){
315 fprintf(stderr,"Error: bit offset %u exceeds length %lu of uint.\n",n,8*sizeof(unsigned int));
316 exit(0);
317 }
318
319
320 /*
321 * Then we have make a mask and shift it over from the first (least
322 * significant) bit in the unsigned int. AND the result with i and
323 * we're done.
324 */
325 mask = 1;
326 mask = mask<<n;
327 /* dumpbits(&mask,32); */
328 /* dumpbits(&i,32); */
329 if(mask & i){
330 return(1);
331 } else {
332 return(0);
333 }
334
335 }
336
337 /*
338 * dumpbits only can dump 8*sizeof(unsigned int) bits at a time.
339 */
dumpbits_left(unsigned int * data,unsigned int nbits)340 void dumpbits_left(unsigned int *data, unsigned int nbits)
341 {
342
343 int i;
344 unsigned int mask;
345
346 if(nbits > 8*sizeof(unsigned int)) {
347 nbits = 8*sizeof(unsigned int);
348 }
349
350 mask = 1;
351 for(i=0;i<nbits;i++){
352 if(mask & *data){
353 printf("1");
354 } else {
355 printf("0");
356 }
357 mask = mask << 1;
358 }
359 printf("\n");
360 }
361
362
bit2uint(char * abit,unsigned int blen)363 unsigned int bit2uint(char *abit,unsigned int blen)
364 {
365
366 int i,bit;
367 unsigned int result;
368
369 /* Debugging
370 if(verbose == D_BITS || verbose == D_ALL){
371 printf("# bit2uint(): converting %s\n",abit);
372 }
373 */
374
375 result = 0;
376 for(i = 0; i < blen; i++){
377 result = result << 1;
378 bit = abit[i] - '0';
379 result += bit;
380 /* Debugging
381 if(verbose == D_BITS || verbose == D_ALL){
382 printf("# bit2uint(): bit[%d] = %d, result = %u\n",i,bit,result);
383 }
384 */
385 }
386
387 /* Debugging
388 if(verbose == D_BITS || verbose == D_ALL){
389 printf("# bit2uint(): returning %0X\n",result);
390 }
391 */
392 return(result);
393
394 }
395
fill_uint_buffer(unsigned int * data,unsigned int buflength)396 void fill_uint_buffer(unsigned int *data,unsigned int buflength)
397 {
398
399 /*
400 * This routine fills *data with random bits from the current
401 * random number generator. Note that MANY generators return
402 * fewer than 32 bits, making this a bit of a pain in the ass.
403 * We need buffers like this for several tests, though, so it
404 * is worth it to create a routine to do this once and for all.
405 */
406
407 unsigned int bufbits,bdelta;
408 unsigned int i,tmp1,tmp2,mask;
409
410 /*
411 * Number of bits we must generate.
412 */
413 bufbits = buflength*sizeof(unsigned int)*CHAR_BIT;
414 bdelta = sizeof(unsigned int)*CHAR_BIT - rmax_bits;
415 mask = 0;
416 for(i=0;i<bdelta;i++) {
417 mask = mask<<1;
418 mask++;
419 }
420 if(verbose == D_BITS || verbose == D_ALL){
421 printf("rmax_bits = %d bdelta = %d\n",rmax_bits,bdelta);
422 }
423
424 for(i=0;i<buflength;i++){
425
426 /* put rmax_bits into tmp1 */
427 tmp1 = gsl_rng_get(rng);
428 /* Cruft
429 printf("tmp1 = %10u = ",tmp1);
430 dumpbits(&tmp1,32);
431 */
432
433 /* Shift it over to the left */
434 tmp1 = tmp1 << bdelta;
435 /*
436 printf("tmp1 = %10u = ",tmp1);
437 dumpbits(&tmp1,32);
438 */
439
440 /* put rmax_bits into tmp2 */
441 tmp2 = gsl_rng_get(rng);
442 /*
443 printf("tmp2 = %10u = ",tmp2);
444 printf("mask = %10u = ",mask);
445 dumpbits(&mask,32);
446 */
447
448 /* mask the second rand */
449 tmp2 = tmp2&mask;
450 /*
451 printf("tmp2 = %10u = ",tmp2);
452 dumpbits(&tmp2,32);
453 */
454
455 /* Fill in the rest of the uint */
456 tmp1 = tmp1 + tmp2;
457 /* Cruft
458 printf("tmp1 = %10u = ",tmp1);
459 dumpbits(&tmp1,32);
460 */
461
462 data[i] = tmp1;
463 }
464
465 }
466
467 /*
468 * OK, the routines above work but they suck. We need a set of SMALL
469 * bitlevel routines for manipulating, aggregating, windowing and so
470 * on, especially if we want to write extended versions of the bit
471 * distribution test.
472 *
473 * On that note, let's generate SMALL routines for:
474 *
475 * a) creating a uint mask() to select bits from uints
476 *
477 * b) grabbing a masked window of bits and left/right shifting it
478 * to an arbitrary offset within the uint (no wraparound).
479 *
480 * c) conjoining two such masked objects to produce a new object.
481 *
482 * d) filling a buffer of arbitrary length with sequential bits from
483 * the selected rng.
484 *
485 * e) Selecting a given window from that buffer with a given bitwise offset
486 * and with periodic wraparound.
487 *
488 * f).... (we'll see what we need)
489 */
490
491
492 /*
493 * This generates a uint-sized mask of 1's starting at bit position
494 * bstart FROM THE LEFT (with 0 being the most significant/sign bit)
495 * and ending at bit position bstop.
496 *
497 * That is:
498 *
499 * umask(3,9) generates a uint containing (first line indicates bit
500 * positions only):
501 * 01234567890123456789012345678901
502 * 00011111110000000000000000000000
503 */
b_umask(unsigned int bstart,unsigned int bstop)504 unsigned int b_umask(unsigned int bstart,unsigned int bstop)
505 {
506
507 unsigned int b,mask,blen;
508
509 if(bstart < 0 || bstop > 31 || bstop < bstart){
510 printf("b_umask() error: bstart <= bstop must be in range 0-31.\n");
511 exit(0);
512 }
513 blen = bstop-bstart+1;
514
515 /*
516 * Create blen 1's on right
517 */
518 mask = 1;
519 for(b=1;b<blen;b++) {
520 mask = mask <<1;
521 mask++;
522 /* dumpbits(&mask,sizeof(uint)*CHAR_BIT); */
523 }
524
525 /*
526 * Now shift them over to the correct starting point.
527 */
528 mask = mask << (32-blen-bstart);
529 /* dumpbits(&mask,sizeof(uint)*CHAR_BIT); */
530
531 return mask;
532
533 }
534
535 /*
536 * This uses b_umask to grab a particular window's worth of bits
537 * from an arbitrary uint and THEN shift it to the new desired offset.
538 * bstart FROM THE LEFT (with 0 being the most significant/sign bit)
539 * and ending at bit position bstop.
540 *
541 * That is:
542 *
543 * b_window(input,2,5,0) generates a uint containing (first line indicates bit
544 * positions only):
545 * input 01101011010000111010101001110110
546 * mask 00111100000000000000000000000000
547 * & 00101000000000000000000000000000
548 * shift 10100000000000000000000000000000
549 */
b_window(unsigned int input,unsigned int bstart,unsigned int bstop,unsigned int boffset)550 unsigned int b_window(unsigned int input,unsigned int bstart,unsigned int bstop,unsigned int boffset)
551 {
552
553 unsigned int mask,output;
554 int shift;
555
556 if(bstart < 0 || bstop > 31 || bstop < bstart){
557 printf("b_umask() error: bstart <= bstop must be in range 0-31.\n");
558 exit(0);
559 }
560 if(boffset < 0 || boffset > 31){
561 printf("b_window() error: boffset must be in range 0-31.\n");
562 exit(0);
563 }
564 shift = bstart - boffset;
565
566 /* dumpbits(&input,sizeof(uint)*CHAR_BIT); */
567 mask = b_umask(bstart,bstop);
568 /* dumpbits(&mask,sizeof(uint)*CHAR_BIT); */
569 output = input & mask;
570 /* dumpbits(&output,sizeof(uint)*CHAR_BIT); */
571 if(shift>0){
572 output = output << shift;
573 } else {
574 output = output >> (-shift);
575 }
576 /* dumpbits(&output,sizeof(uint)*CHAR_BIT); */
577
578 return output;
579
580 }
581
582 /*
583 * Rotate the uint left (with periodic BCs)
584 */
b_rotate_left(unsigned int input,unsigned int shift)585 unsigned int b_rotate_left(unsigned int input,unsigned int shift)
586 {
587
588 unsigned int tmp;
589
590 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);
591 tmp = b_window(input,0,shift-1,32-shift);
592 dumpbits(&tmp,sizeof(unsigned int)*CHAR_BIT);
593 input = input << shift;
594 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);
595 input += tmp;
596 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);
597
598 return input;
599
600 }
601
602 /*
603 * Rotate the uint right (with periodic BCs)
604 */
b_rotate_right(unsigned int input,unsigned int shift)605 unsigned int b_rotate_right(unsigned int input, unsigned int shift)
606 {
607
608 unsigned int tmp;
609
610 if(shift == 0) return(input);
611 MYDEBUG(D_BITS) {
612 printf("Rotate right %d\n",shift);
613 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);printf("|");
614 }
615 tmp = b_window(input,32-shift,31,0);
616 MYDEBUG(D_BITS) {
617 dumpbits(&tmp,sizeof(unsigned int)*CHAR_BIT);printf("\n");
618 }
619 input = input >> shift;
620 MYDEBUG(D_BITS) {
621 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);printf("|");
622 }
623 input += tmp;
624 MYDEBUG(D_BITS) {
625 dumpbits(&input,sizeof(unsigned int)*CHAR_BIT);printf("\n\n");
626 }
627
628 return(input);
629
630 }
631
632 /*
633 * OK, with this all in hand, we can NOW write routines to return
634 * pretty much any sort of string of bits from the prevailing rng
635 * without too much effort. Let's get an ntuple from a uint vector
636 * of arbitrary length and offset, with cyclic boundary conditions.
637 *
638 * We have to pack the answer into the LEAST significant bits in the
639 * output vector, BTW, not the MOST. That is, we have to fill the
640 * output window all the way to the rightmost bit. Tricky.
641 *
642 * I think that I can make this 2-3 times faster than it is by using
643 * John E. Davis's double buffering trick. In context, it would be:
644 * 1) Limit return size to e.g. 32 bits. I think that this is fair;
645 * for the moment I can't see needing more than a uint return, but it
646 * would be easy enough to generate an unsigned long long (64 bit)
647 * uint return if we ever get to where it would help. For example,
648 * by calling this routine twice if nothing else.
649 * 2) Pad the input buffer by cloning the first uint onto the end
650 * to easily manage the wraparound.
651 * 3) Use a dynamic buffer to rightshift directly into alignment
652 * with rightmost part of output.
653 * 4) IF NECESSARY Use a dynamic buffer to leftshift from the previous
654 * word into alignment with the rightmost in the output.
655 * 5) Mask the two parts and add (or logical and) them.
656 * 6) Return. Note that the contents of the starting buffer do not
657 * change, and the two dynamic buffers are transient.
658 *
659 * BUT, we're not going to mess with that NOW unless we must. The routine
660 * below is AFAIK tested and reliable, if not optimal.
661 */
get_ntuple_cyclic(unsigned int * input,unsigned int ilen,unsigned int * output,unsigned int jlen,unsigned int ntuple,unsigned int offset)662 void get_ntuple_cyclic(unsigned int *input,unsigned int ilen,
663 unsigned int *output,unsigned int jlen,unsigned int ntuple,unsigned int offset)
664 {
665
666 /* important bitlevel indices */
667 int i,j,bs,be,bu,br1,br2;
668 /* counter of number of bits remaining to be parsed */
669 int bleft;
670
671
672 /*
673 * Now we set all the bit indices.
674 */
675 bu = sizeof(unsigned int)*CHAR_BIT; /* index/size of uint in bits */
676 bs = offset%bu; /* starting bit */
677 be = (offset + ntuple)%bu; /* ending bit */
678 if(be == 0) be = bu; /* point PAST end of last bit */
679 br1 = be - bs; /* For Rule 1 */
680 br2 = bu - bs; /* For Rule 2 */
681 MYDEBUG(D_BITS) {
682 printf("bu = %d, bs = %d, be = %d, br1 = %d, br2 = %d\n",
683 bu,bs,be,br1,br2);
684 }
685
686 /*
687 * Set starting i (index of uint containing last bit) and j (the last
688 * index in output). We will impose periodic wraparound on i inside the
689 * main loop.
690 */
691 i = (offset+ntuple)/bu;
692 j = jlen - 1;
693 if(be == bu) i--; /* Oops. be is whole line exactly */
694 i = i%ilen; /* Periodic wraparound on start */
695 MYDEBUG(D_BITS) {
696 printf("i = %d, j = %d\n",i,j);
697 }
698
699 /*
700 * Always zero output
701 */
702 memset(output,0,jlen*sizeof(unsigned int));
703
704 /*
705 * Number of bits left to parse out
706 */
707 bleft = ntuple;
708
709 /*
710 * First we handle the trivial short cases -- one line of input
711 * mapping to one line of output. These are cases that are very
712 * difficult for the rules below to catch correctly, as they presume
713 * at least one cycle of the Right-Left rules.
714 */
715
716 /*
717 * Start with all cases where the input lives on a single line and runs
718 * precisely to the end (be = bu). Apply Rule 2 to terminate. That way
719 * Rule 2 below can be CERTAIN that it is being invoked after a right
720 * fill (only).
721 */
722 if(bleft == br2) {
723 MYDEBUG(D_BITS) {
724 printf("Rule 2a: From input[%d] to output[%d] = ",i,j);
725 }
726 output[j] += b_window(input[i],bs,bu-1,bu-br2);
727 bleft -= br2;
728 MYDEBUG(D_BITS) {
729 dumpuintbits(&output[j],1);printf("\n");
730 printf("bleft = %d\n",bleft);
731 printf("Rule 2a: terminate.\n");
732 }
733 }
734
735 /*
736 * Similarly, resolve all cases where the input lives on a single line
737 * and runs from start to finish within the line (so e.g. be <= bu-1,
738 * bs >= 0).
739 */
740 if(bleft == br1) {
741 MYDEBUG(D_BITS) {
742 printf("Rule 1a: From input[%d] to output[%d] = ",i,j);
743 }
744 output[j] = b_window(input[i],bs,be-1,bu-bleft);
745 bleft -= br1;
746 MYDEBUG(D_BITS) {
747 dumpuintbits(&output[j],1);printf("\n");
748 printf("bleft = %d\n",bleft);
749 printf("Rule 1a: terminate.\n");
750 }
751 }
752
753
754
755 while(bleft > 0){
756
757 /*
758 * Rule 1
759 */
760 if(bleft == br1) {
761 MYDEBUG(D_BITS) {
762 printf("Rule 1: From input[%d] to output[%d] = ",i,j);
763 }
764 output[j] = b_window(input[i],bs,be-1,bu-bleft);
765 bleft -= br1;
766 MYDEBUG(D_BITS) {
767 dumpuintbits(&output[j],1);printf("\n");
768 printf("bleft = %d\n",bleft);
769 printf("Rule 1: terminate.\n");
770 }
771 break; /* Terminate while loop */
772 }
773
774 /*
775 * Rule Right -- with termination check
776 */
777 if(bleft != 0) {
778 MYDEBUG(D_BITS) {
779 printf("Rule R: From input[%d] to output[%d] = ",i,j);
780 }
781 output[j] += b_window(input[i],0,be-1,bu-be);
782 bleft -= be;
783 MYDEBUG(D_BITS) {
784 dumpuintbits(&output[j],1);printf("\n");
785 printf("bleft = %d\n",bleft);
786 }
787 i--;
788 if(i<0) i = ilen-1; /* wrap i around */
789 } else {
790 MYDEBUG(D_BITS) {
791 printf("Rule R: terminate.\n");
792 }
793 break; /* Terminate while loop */
794 }
795
796 /*
797 * This rule terminates if Rule Right is getting whole lines and
798 * we're down to the last whole or partial line. In this case we
799 * have to decrement j on our own, as we haven't yet reached
800 * Rule Left.
801 * Rule 2b
802 */
803 if(bleft == br2 && be == bu ) {
804 j--;
805 MYDEBUG(D_BITS) {
806 printf("Rule 2b: From input[%d] to output[%d] = ",i,j);
807 }
808 output[j] += b_window(input[i],bs,bu-1,bu - br2);
809 bleft -= br2;
810 MYDEBUG(D_BITS) {
811 dumpuintbits(&output[j],1);printf("\n");
812 printf("bleft = %d\n",bleft);
813 printf("Rule 2b: terminate.\n");
814 }
815 break; /* Terminate while loop */
816 }
817
818
819 /*
820 * This rule terminates when Rule Right is getting partial lines.
821 * In this case we KNOW that we must terminate with a Rule 2
822 * partial line.
823 * Rule 2c
824 */
825 if(bleft == br2 && br2 < bu) {
826 MYDEBUG(D_BITS) {
827 printf("Rule 2c: From input[%d] to output[%d] = ",i,j);
828 }
829 output[j] += b_window(input[i],bs,bu-1,bs - be);
830 bleft -= br2;
831 MYDEBUG(D_BITS) {
832 dumpuintbits(&output[j],1);printf("\n");
833 printf("bleft = %d\n",bleft);
834 printf("Rule 2c: terminate.\n");
835 }
836 break; /* Terminate while loop */
837 }
838
839
840 /*
841 * Rule Left -- with termination check
842 */
843 if(bleft != 0) {
844 if(be != bu) {
845 /*
846 * We skip Rule Left if Rule Right is getting full lines
847 */
848 MYDEBUG(D_BITS) {
849 printf("Rule L: From input[%d] to output[%d] = ",i,j);
850 }
851 output[j] += b_window(input[i],be,bu-1,0);
852 bleft -= bu-be;
853 MYDEBUG(D_BITS) {
854 dumpuintbits(&output[j],1);printf("\n");
855 printf("bleft = %d\n",bleft);
856 }
857 }
858 } else {
859 MYDEBUG(D_BITS) {
860 printf("Rule L: terminate.\n");
861 }
862 break; /* Terminate while loop */
863 }
864 /*
865 * With this arrangment we can always decrement the second loop counter
866 * here.
867 */
868 j--;
869
870 }
871
872 }
873
874 /*
875 * The last thing I need to make (well, it may not be the last thing,
876 * we'll see) is a routine that
877 *
878 * a) fills an internal static circulating buffer with random bits pulled
879 * from the current rng.
880 *
881 * b) returns a rand of any requested size (a void * routine with a
882 * size parameter in bits or bytes) using the previous routine, keep
883 * track of the current position in the periodic buffer with a static
884 * pointer.
885 *
886 * c) refills the circulating buffer from the current rng.
887 *
888 * Note well that this should be the ONLY point of access to even the
889 * gsl rngs, as they do not all return the same number of bits. We need
890 * to be able to deal with e.g. 24 bit rands, 31 bit rands (quite a few
891 * of them) and 32 bit uint rands. This routine will completely hide this
892 * level of detail from the caller and permit any number of bitlevel tests
893 * to be conducted on the One True Bitstream produced by the generator
894 * without artificial gaps or compression.
895 *
896 * Note that this routine is NOT portable (although it could be made to
897 * be portable) and requires that global rng exist and be set up ready to go
898 * by the calling routine.
899 */
900
901 static unsigned int bits_rand[2]; /* A buffer that can handle partial returns */
902 static int bleft = -1; /* Number of bits we still need in rand[1] */
903
get_uint_rand(gsl_rng * gsl_rng)904 unsigned int get_uint_rand(gsl_rng *gsl_rng)
905 {
906
907 static unsigned int bl,bu,tmp;
908
909 /*
910 * First call -- initialize/fill bits_rand from current rng. bl and bu
911 * should be static so they are preserved for later calls.
912 */
913 if(bleft == -1){
914 /* e.g. 32 */
915 bu = sizeof(unsigned int)*CHAR_BIT;
916 /* e.g. 32 - 31 = 1 for a generator that returns 31 bits */
917 bl = bu - rmax_bits;
918 /* For the first call, we start with bits_rand[1] all or partially filled */
919 bits_rand[0] = 0;
920 bits_rand[1] = gsl_rng_get(gsl_rng);
921 /* This is how many bits we still need. */
922 bleft = bu - rmax_bits;
923 /*
924 * The state of the generator is now what it would be on a
925 * typical running call. bits_rand[1] contains the leftover bits from the
926 * last call (if any). We now have to interatively fill bits_rand[0],
927 * grab (from the RIGHT) just the number of bits we need to fill the
928 * rest of bits_rand[1] (which might be zero bits). Then we save bits_rand[1]
929 * for return and move the LEFTOVER (unused) bits from bits_rand[0] into
930 * bits_rand[1], adjust bleft accordingly, and return the uint bits_rand.
931 */
932 MYDEBUG(D_BITS) {
933 printf("bu = %d bl = %d\n",bu,bl);
934 printf(" init: |");
935 dumpbits(&bits_rand[0],bu);
936 printf("|");
937 dumpbits(&bits_rand[1],bu);
938 printf("|\n");
939 }
940 }
941
942 /*
943 * We have to iterate into range because it is quite possible that
944 * rmax_bits won't be enough to fill bits_rand[1].
945 */
946 while(bleft > rmax_bits){
947 /* Get a bits_rand's worth (rmax_bits) into bits_rand[0] */
948 bits_rand[0] = gsl_rng_get(gsl_rng);
949 MYDEBUG(D_BITS) {
950 printf("before %2d: |",bleft);
951 dumpbits(&bits_rand[0],bu);
952 printf("|");
953 dumpbits(&bits_rand[1],bu);
954 printf("|\n");
955 }
956 /* get the good bits only and fill in bits_rand[1] */
957 bits_rand[1] += b_window(bits_rand[0],bu-rmax_bits,bu-1,bleft-rmax_bits);
958 MYDEBUG(D_BITS) {
959 printf(" after %2d: |",bleft);
960 dumpbits(&bits_rand[0],bu);
961 printf("|");
962 dumpbits(&bits_rand[1],bu);
963 printf("|\n");
964 }
965 bleft -= rmax_bits; /* Number of bits we still need to fill bits_rand[1] */
966 }
967
968 /*
969 * We are now in range. We get just the number of bits we need, from
970 * the right of course, and add them to bits_rand[1].
971 */
972 bits_rand[0] = gsl_rng_get(gsl_rng);
973 MYDEBUG(D_BITS) {
974 printf("before %2d: |",bleft);
975 dumpbits(&bits_rand[0],bu);
976 printf("|");
977 dumpbits(&bits_rand[1],bu);
978 printf("|\n");
979 }
980 if(bleft != 0) {
981 bits_rand[1] += b_window(bits_rand[0],bu-bleft,bu-1,0);
982 }
983 MYDEBUG(D_BITS) {
984 printf(" after %2d: |",bleft);
985 dumpbits(&bits_rand[0],bu);
986 printf("|");
987 dumpbits(&bits_rand[1],bu);
988 printf("|\n");
989 }
990 /* Save for return */
991 tmp = bits_rand[1];
992 /*
993 * Move the leftover bits from bits_rand[0] into bits_rand[1] (right
994 * justified), adjust bleft accordingly, and return. Note that if we
995 * exactly filled the return with ALL the bits in rand[0] then we
996 * need to start over on the next one.
997 */
998 if(bleft == rmax_bits){
999 bleft = bu;
1000 } else {
1001 bits_rand[1] = b_window(bits_rand[0],bu-rmax_bits,bu-bleft-1,bu-rmax_bits+bleft);
1002 bleft = bu - rmax_bits + bleft;
1003 MYDEBUG(D_BITS) {
1004 printf(" done %2d: |",bleft);
1005 dumpbits(&bits_rand[0],bu);
1006 printf("|");
1007 dumpbits(&bits_rand[1],bu);
1008 printf("|\n");
1009 }
1010 }
1011 return(tmp);
1012
1013 }
1014
1015 /*
1016 * With get_uint(rand() in hand, we can FINALLY create a routine that
1017 * can give us neither more nor less than the "next N bits" from the
1018 * random number stream, without dropping any. The return can even be
1019 * of arbitrary size -- we make the return a void pointer whose size is
1020 * specified by the caller (and guaranteed to be big enough to hold
1021 * the result).
1022 */
1023
1024 /*
1025 * We'll use a BIG static circulating buffer so we can handle BIG
1026 * lags without worrying too much about it. Space is cheap in the
1027 * one-page range.
1028 */
1029 #define BRBUF 6
1030 static unsigned int bits_randbuf[BRBUF];
1031 static unsigned int bits_output[BRBUF];
1032 /* pointer to line containing LAST return */
1033 static int brindex = -1;
1034 /* pointer to region being backfilled */
1035 static int iclear = -1;
1036 /* pointer to the last (most significant) returned bit */
1037 static int bitindex = -1;
1038
get_rand_bits(void * result,unsigned int rsize,unsigned int nbits,gsl_rng * gsl_rng)1039 void get_rand_bits(void *result,unsigned int rsize,unsigned int nbits,gsl_rng *gsl_rng)
1040 {
1041
1042 int i,offset;
1043 unsigned int bu;
1044 char *output,*resultp;
1045
1046 /*
1047 * Zero the return. Note rsize is in characters/bytes.
1048 */
1049 memset(result,0,rsize);
1050 MYDEBUG(D_BITS) {
1051 printf("Entering get_rand_bits. rsize = %d, nbits = %d\n",rsize,nbits);
1052 }
1053
1054 /*
1055 * We have to do a bit of testing on call parameters. We cannot return
1056 * more bits than the result buffer will hold. We return 0 if nbits = 0.
1057 * We cannot return more bits than bits_randbuf[] will hold.
1058 */
1059 bu = sizeof(unsigned int)*CHAR_BIT;
1060 if(nbits == 0) return; /* Handle a "dumb call" */
1061 if(nbits > (BRBUF-2)*bu){
1062 fprintf(stderr,"Warning: get_rand_bits capacity exceeded!\n");
1063 fprintf(stderr," nbits = %d > %d (nbits max)\n",nbits,(BRBUF-2)*bu);
1064 return;
1065 }
1066 if(nbits > rsize*CHAR_BIT){
1067 fprintf(stderr,"Warning: Cannot get more bits than result vector will hold!\n");
1068 fprintf(stderr," nbits = %d > %d (rsize max bits)\n",nbits,rsize*CHAR_BIT);
1069 return; /* Unlikely, but possible */
1070 }
1071
1072 if(brindex == -1){
1073 /*
1074 * First call, fill the buffer BACKWARDS. I know this looks odd,
1075 * but we have to think of bits coming off the generator from least
1076 * significant on the right to most significant on the left as
1077 * filled by get_uint_rand(), so we have to do it this way to avoid
1078 * a de-facto shuffle for generators with rmax_bits < 32.
1079 */
1080 for(i=BRBUF-1;i>=0;i--) {
1081 bits_randbuf[i] = get_uint_rand(gsl_rng);
1082 /* printf("bits_randbuf[%d] = %u\n",i,bits_randbuf[i]); */
1083 }
1084 /*
1085 * Set the pointers to point to the last line, and the bit AFTER the
1086 * last bit. Note that iclear should always start equal to brindex
1087 * as one enters the next code segment.
1088 */
1089 brindex = BRBUF;
1090 iclear = brindex-1;
1091 bitindex = 0;
1092 MYDEBUG(D_BITS) {
1093 printf("Initialization: iclear = %d brindex = %d bitindex = %d\n",iclear,brindex,bitindex);
1094 }
1095 }
1096 MYDEBUG(D_BITS) {
1097 for(i=0;i<BRBUF;i++){
1098 printf("%2d: ",i);
1099 dumpuintbits(&bits_randbuf[i],1);
1100 printf("\n");
1101 }
1102 }
1103 /*
1104 * OK, the logic here is: grab a window that fills the bit request
1105 * precisely (determining the starting buffer index and offset
1106 * beforehand) and put it into bits_output; backfill WHOLE uints from
1107 * the END of the window to the last uint before the BEGINNING of the
1108 * window, (in reverse order!)
1109 */
1110
1111 /*
1112 * Get starting indices. Shift the buffer index back by the number of
1113 * whole uints in nbits, then shift back the bit index back by the
1114 * modulus/remainder, then handle a negative result (borrow), then finally
1115 * deal with wraparound of the main index as well.
1116 */
1117 brindex -= nbits/bu;
1118 bitindex = bitindex - nbits%bu;
1119 if(bitindex < 0) {
1120 /* Have to borrow from previous uint */
1121 brindex--; /* So we push back one more */
1122 bitindex += bu; /* and find the new bitindex */
1123 }
1124 if(brindex < 0) brindex += BRBUF; /* Oops, need to wrap around */
1125 MYDEBUG(D_BITS) {
1126 printf(" Current Call: iclear = %d brindex = %d bitindex = %d\n",iclear,brindex,bitindex);
1127 }
1128
1129 /*
1130 * OK, so we want a window nbits long, starting in the uint indexed
1131 * by brindex, displaced by bitindex.
1132 */
1133 offset = brindex*bu + bitindex;
1134 MYDEBUG(D_BITS) {
1135 printf(" Window Call: tuple = %d offset = %d\n",nbits,offset);
1136 }
1137 get_ntuple_cyclic(bits_randbuf,BRBUF,bits_output,BRBUF,nbits,offset);
1138 /* Handle case where we returned whole uint at brindex location */
1139 MYDEBUG(D_BITS) {
1140 printf(" Cleaning up: iclear = %d brindex = %d bitindex = %d\n",iclear,brindex,bitindex);
1141 }
1142
1143 /*
1144 * Time to backfill. We walk backwards, filling until we reach
1145 * the current index.
1146 */
1147 while(iclear != brindex){
1148 bits_randbuf[iclear--] = get_uint_rand(gsl_rng);
1149 if(iclear < 0) iclear += BRBUF; /* wrap on around */
1150 }
1151 /*
1152 * Dump the refilled buffer
1153 */
1154 MYDEBUG(D_BITS) {
1155 for(i=0;i<BRBUF;i++){
1156 printf("%2d: ",i);
1157 dumpuintbits(&bits_randbuf[i],1);
1158 printf("\n");
1159 }
1160 }
1161
1162 /*
1163 * At this point iclear SHOULD equal brindex, guaranteed, and bits_output
1164 * contains the answer desired. However, NOW we have to copy this answer
1165 * back into result, a byte at a time, in reverse order.
1166 */
1167 MYDEBUG(D_BITS) {
1168 printf("bits_output[%d] = ",BRBUF-1);
1169 dumpuintbits(&bits_output[BRBUF-1],1);
1170 printf("\n");
1171 }
1172
1173 /*
1174 * Get and align addresses of char *pointers into bits_output and result
1175 */
1176 output = (char *)&bits_output[BRBUF]-rsize;
1177 resultp = (char *)result;
1178 MYDEBUG(D_BITS) {
1179 printf("rsize = %d output address = %p result address = %p\n",rsize,output,resultp);
1180 }
1181
1182 /* copy them over characterwise */
1183 for(i=0;i<rsize;i++){
1184 resultp[i] = output[i];
1185 MYDEBUG(D_BITS) {
1186 printf(" Returning: result[%d} = ",i);
1187 dumpbits((unsigned int *)&resultp[i],8);
1188 printf(" output[%d} = ",i);
1189 dumpbits((unsigned int *)&output[i],8);
1190 printf("\n");
1191 }
1192 }
1193
1194 }
1195
1196 /*
1197 * OK, I CLEARLY need this. What it will do is take a source and
1198 * destination address and BIT level offsets therein and copy
1199 * src into dest all aligned and everything.
1200 *
1201 * Example:
1202 * dst = 01100000 00000000, doffset = 3
1203 * src = 10100111 11100100, soffset = 7, slen = 9
1204 *
1205 * dst = 01111110 01000000
1206 */
mybitadd(char * dst,int doffset,char * src,int soffset,int slen)1207 void mybitadd(char *dst, int doffset, char *src, int soffset, int slen)
1208 {
1209
1210 int sindex,dindex;
1211 int sblen;
1212 unsigned int tmp;
1213 char *btmp;
1214
1215 btmp = (char *)(&tmp + 2); /* we only need the last two bytes of tmp */
1216
1217 sindex = soffset/CHAR_BIT; /* index of first source byte */
1218 soffset = soffset%CHAR_BIT; /* index WITHIN first source byte */
1219 dindex = doffset/CHAR_BIT; /* index of first destination byte */
1220 doffset = doffset%CHAR_BIT; /* index WITHIN first destination byte */
1221 sblen = CHAR_BIT - soffset; /* assume we go to byte boundary (std form) */
1222
1223 printf("sindex = %d soffset = %d dindex = %d doffset = %d sblen = %d\n",
1224 sindex,soffset,dindex,doffset,sblen);
1225 while(slen > 0){
1226 tmp = 0;
1227 tmp = (unsigned int) src[sindex++]; /* Put current source byte into workspace. */
1228 tmp = 255;
1229 printf("Source byte %2d= ",sindex-1);
1230 /* dumpbitwin((char *)&tmp,4,0,32); */
1231 printf("\n");
1232 /*
1233 * This signals the final byte to process
1234 */
1235 if(sblen >= slen){
1236 sblen = slen; /* number of bits we get */
1237 }
1238 tmp = tmp >> (CHAR_BIT - soffset - sblen); /* right shift to byte edge */
1239 soffset = CHAR_BIT - sblen; /* fix offset */
1240
1241 /*
1242 * tmp is now in "standard form" -- right aligned, with
1243 * sblen = CHAR_BIT - soffset. We don't care how we got there -- now
1244 * we just put it away.
1245 */
1246 tmp = tmp << (CHAR_BIT+soffset-doffset); /* align with target bytes */
1247 dst[dindex] += btmp[0]; /* always add in left byte */
1248
1249 /*
1250 * This is the final piece of trickiness. If the left byte is too small
1251 * to reach the right margin of dst[dindex], we do NOT increment dindex,
1252 * instead we increment doffset by sblen and are done. Otherwise we
1253 * go ahead and increment dindex and add in the second byte. We have to
1254 * be careful with the boundary case where sblen PRECISELY fills the
1255 * first byte, as then we want to increment dindex but set doffset to 0.
1256 */
1257 if(soffset >= doffset){
1258 doffset += sblen;
1259 if(doffset == CHAR_BIT){
1260 dindex++;
1261 doffset = 0;
1262 }
1263 } else {
1264 dindex++;
1265 dst[dindex] = btmp[1];
1266 doffset = sblen - CHAR_BIT + doffset;
1267 }
1268
1269 slen -= sblen; /* This accounts for the chunk we've just gotten */
1270
1271 }
1272
1273 }
1274
1275 /* static unsigned int pattern_output[BRBUF]; */
1276
get_rand_pattern(void * result,unsigned int rsize,int * pattern,gsl_rng * gsl_rng)1277 void get_rand_pattern(void *result,unsigned int rsize,int *pattern,gsl_rng *gsl_rng)
1278 {
1279
1280 int i,j,pindex,poffset;
1281 unsigned int bu,nbits,tmpuint;
1282 char *resultp;
1283
1284 MYDEBUG(D_BITS) {
1285 printf("# get_rand_pattern: Initializing with rsize = %d\n",rsize);
1286 }
1287
1288 /*
1289 * Count the number of bits in the actual returned object.
1290 */
1291 i = 0;
1292 nbits = 0;
1293 while(pattern[i]){
1294 if(pattern[i]>0) nbits += pattern[i];
1295 /*
1296 * Sorry, I want to use a uint to hold snippets from get_rand_bits().
1297 * So we must bitch if we try to use more and quit.
1298 */
1299 if(pattern[i]>32) {
1300 fprintf(stderr,"Error: pattern[%d] = %d chunks must not exceed 32 in length.\n",i,pattern[i]);
1301 fprintf(stderr," Use contiguous 32 bit pieces to create a longer chunk.\n");
1302 exit(0);
1303 }
1304 MYDEBUG(D_BITS) {
1305 printf("# get_rand_pattern: pattern[%d] = %d nbits = %u\n",i,pattern[i],nbits);
1306 }
1307 i++;
1308 }
1309
1310 /*
1311 * Zero the return. Note rsize is in characters/bytes.
1312 */
1313 memset(result,0,rsize);
1314
1315 /*
1316 * We have to do a bit of testing on call parameters. We cannot return
1317 * more bits than the result buffer will hold. We return 0 if nbits = 0.
1318 * We cannot return more bits than bits_randbuf[] or result[] will hold.
1319 */
1320 bu = sizeof(unsigned int)*CHAR_BIT;
1321 if(nbits == 0) return; /* Handle a "dumb call" */
1322 if(nbits > (BRBUF-2)*bu){
1323 fprintf(stderr,"Warning: get_rand_bits capacity exceeded!\n");
1324 fprintf(stderr," nbits = %d > %d (nbits max)\n",nbits,(BRBUF-2)*bu);
1325 return;
1326 }
1327 if(nbits > rsize*CHAR_BIT){
1328 fprintf(stderr,"Warning: Cannot get more bits than result vector will hold!\n");
1329 fprintf(stderr," nbits = %d > %d (rsize max bits)\n",nbits,rsize*CHAR_BIT);
1330 return; /* Unlikely, but possible */
1331 }
1332
1333 /*
1334 * This should really be pretty simple. nbits holds the displacement
1335 * BACKWARDS from the end of the return. We therefore:
1336 *
1337 * a) Get the ith chunk into tmpuint OR iterate calls to skip ith bits.
1338 * b) if we got a chunk, fill it into resultp[] bytewise by e.g.
1339 * rotating left or right to align the piece and masking it into
1340 * place. decrement nbits as we go by the number of bits we've filled
1341 * in (adjusting resultp index and bit pointer as we go).
1342 * c) iterate until pattern[i] == 0 AND nbits = 0 (done) and return.
1343 *
1344 * Get and align addresses of char *pointers for (void *)result and
1345 * tmpuint to make it relatively easy to line up and generate result bytes.
1346 */
1347
1348 /*
1349 * Set up index and pointer into resultp as usual. Remember this is
1350 * BYTEWISE, not UINTWISE.
1351 *
1352 * For example, suppose rsize = 4 bytes and nbits = 28 bits. Then
1353 * we want pindex = 0 (it starts to fill in the first byte of resultp[])
1354 * and poffset = 4. 28/8 = 3 (remainder 4) so:
1355 */
1356 pindex = rsize - nbits/CHAR_BIT - 1;
1357 poffset = nbits%CHAR_BIT;
1358
1359 while(nbits != 0){
1360
1361 if(pattern[i] > 0){
1362
1363 /*
1364 * Get pattern[i] bits (in uint chunks)
1365 */
1366 j = pattern[i];
1367 while(j>bu) {
1368
1369 get_rand_bits(&tmpuint,sizeof(unsigned int),bu,rng);
1370 /*
1371 * Pack this whole uint into result at the offset.
1372 */
1373 mybitadd((char *)(&resultp + pindex),poffset,(char *)&tmpuint,0,bu);
1374
1375 /*
1376 * Decrement j, increment pindex, poffset remains unchanged.
1377 */
1378 j -= bu;
1379 pindex += sizeof(unsigned int);
1380
1381 }
1382
1383 get_rand_bits(&tmpuint,sizeof(unsigned int),j,rng);
1384 /*
1385 * Pack this partial uint into resultp
1386 */
1387 mybitadd((char *)(&resultp + pindex),poffset,(char *)&tmpuint,bu-j,j);
1388
1389 /*
1390 * Done with pattern, decrement nbits
1391 */
1392 nbits -= pattern[i];
1393
1394 } else if(pattern[i] < 0){
1395
1396 /* Skip -pattern[i] bits */
1397 j = -pattern[i];
1398 while(j>bu) {
1399 /* skip whole uint's worth */
1400 get_rand_bits(&tmpuint,sizeof(unsigned int),bu,rng);
1401 j -= bu;
1402
1403 }
1404 /* skip final remaining <bu chunk */
1405 get_rand_bits(&tmpuint,sizeof(unsigned int),j,rng);
1406
1407 } else {
1408
1409 /* We SHOULD terminate by running out of nbits exactly... */
1410 fprintf(stdout,"# get_rand_pattern(): Sorry, this cannot happen.\n\
1411 If it did, then you're in deep trouble bugwise. Refer to rgb.\n");
1412 exit(0);
1413
1414 }
1415
1416 }
1417
1418
1419 }
1420
1421 /*
1422 * The bits.c module doesn't malloc anything, but it does maintain some
1423 * static buffers that must be cleared in order to achieve consistent
1424 * results from a rng reseed on, per run.
1425 */
reset_bit_buffers()1426 void reset_bit_buffers()
1427 {
1428
1429 int i;
1430
1431 bits_rand[0] = bits_rand[1] = 0;
1432 bleft = -1;
1433 for(i = 0;i<BRBUF;i++){
1434 bits_randbuf[i] = 0;
1435 bits_output[i] = 0;
1436 }
1437 brindex = -1;
1438 iclear = -1;
1439 bitindex = -1;
1440
1441 }
1442