[M3devel] uid to string conversion? (probably answered my own question)

Jay K jay.krell at cornell.edu
Sat Sep 25 12:47:56 CEST 2010


static void
fmt_uid (unsigned long x, char *buf)
{
  unsigned i = UID_SIZE;
  static const char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  gcc_assert (sizeof(alphabet) == 63);

  if (x == NO_UID)
  {
    static const char zzzzzz[] = "zzzzzz";
    memcpy (buf, zzzzzz, sizeof(zzzzzz));
    return;
  }

  buf[i] = 0;
  while (i)
  {
    buf[--i] = alphabet[x % 62];
    x /= 62;
  }

  if (x || buf[0] < 'A' || buf[0] > 'Z')
    fatal_error (" *** bad uid -> identifier conversion!!");
}

1) what guarantees buf[0] is valid, in that last chunk?
Is it because uids have a limited range and they'd have to be too large to fail there?
Because 62^6 is larger than 2^32?

2) The check is too tight anyway? It should allow also lowercase a-z?

1) I guess so:

#include <stdlib.h>
#include <stdio.h>

unsigned multu32(unsigned a, unsigned b)
{
  unsigned long long c = (a * (unsigned long long)b);
  if (c != (unsigned)c) /* or   if (c > ~(unsigned)0) */
  {
    printf("overflow %u * %u; %x * %x\n", a, b, a, b);
    exit(0);
  }
  return c;
}

int main()
{
unsigned a = 1;
unsigned i = { 0 };
for (; i < 20; ++i)
{
  printf("%u: %u %x\n", i, a, a);
  a = multu32(a, 62);
}
return 0;
}

jbook2:p248 jay$ gcc 1.c 
jbook2:p248 jay$ ./a.out
0: 1 1
1: 62 3e
2: 3844 f04
3: 238328 3a2f8
4: 14776336 e17810
5: 916132832 369b13e0
overflow 916132832 * 62; 369b13e0 * 3e


 - Jay
 		 	   		  


More information about the M3devel mailing list