• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
  • Campbell Ritchie
  • Ron McLeod
  • Junilu Lacar
  • Paul Clapham
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Rob Spoor
  • Bear Bibeault
Saloon Keepers:
  • Tim Moores
  • Tim Holloway
  • Piet Souris
  • Carey Brown
  • Stephan van Hulst
  • Frits Walraven
  • fred rosenberger
  • salvin francis

String of Decimal Digits from Random Bytes

Posts: 3596
Android Eclipse IDE TypeScript Redhat MicroProfile Quarkus Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I need to generate random PIN and PUK codes which will be used in SIM profiles.  The codes will typically be between 4 and 8 digits.

The random source is a HSM and is accessed over a HTTP/2 based network connection (actually gRPC).  The cost to call the HSM is high compared to the cost of the number of bytes being requested (for example, to get 20 bytes, it is way more costly to make 20 single bytes requests compared to one 20 byte request).  The random digit strings must have the same degree of randomness as the bytes provided by the HSM.

There is also a requirement to use Java 11.

I have found two solutions which seem to work well, but I would be interested in hearing about any other ideas, or suggestion on how to improve what I am done.

The first approach is to use a BigInteger, constructed from an array of random bytes large enough to create a value with sufficient length, and then use the last n digits of the String representation.  Since the String representation does not include leading zero, they may need to prepended to returned value.

I found that if the number of bytes used was too small, then the distribution would be biased, favouring the lower-order digits.

The other approach was to split the bytes in to nibbles/semi-octets, and filter-out any values greater than 9.  Doing this, there is the chance that a large number (potentially all) of the bytes provided could contain nibble values which were larger than 9, so it is not possible to predict how many bytes would be needed from the HSM in-advance.  I implemented a stateful supplier which would request a number of bytes based on a hint, filter them, and then provide one at a time them as required,  If the demand exhausted the number of stored filtered values, it would request another lot of bytes.

Both implementations perform similarly in terms if distribution and execute time, but the using BigInteger around 50% faster.

You showed up just in time for the waffles! And this tiny ad:
Building a Better World in your Backyard by Paul Wheaton and Shawn Klassen-Koop
    Bookmark Topic Watch Topic
  • New Topic