code: private String generateTOTP(long time) {
          // Calculate the number of time steps between the initial counter time
          // (i.e. T0 = 0 = Unix epoch) and the specified 'time'.
          final long tc = (long) Math.floor(time / timeStep);
  
          // Using the counter
          // First 8 bytes are for the movingFactor
          // Compliant with base RFC 4226 (HOTP)
          String timeInHex = Strings.padStart(Long.toHexString(tc).toUpperCase(Locale.ENGLISH), 16, '0');
  
          // Step 1: Generate the HMAC-SHA hash.
          byte[] msg = BaseEncoding.base16().decode(timeInHex);
          byte[] hash = computeHmacSha(key, msg);
  
          // Step 2: Dynamic Truncation as per section 5.3 of RFC 4226.
          // -
          // "... Let OffsetBits be the low-order 4 bits of String[19] (where String = String[0]...String[19]) ..."
          // -
          // "... Let P = String[OffSet]...String[OffSet+3] ... Return the Last 31 bits of P ..."
          int offset = hash[hash.length - 1] & 0xf;
          int binary = ((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff);
  
          // Step 3: Compute the TOTP value.
          int otp = binary % ((int) Math.pow(10, digits));
  
          // Ensure the TOTP value contains the specified number of digits.
          return Strings.padStart(Integer.toString(otp), digits, '0');
      }
docs: Returns the Time-based One-time Password value against an arbitrary
  {@code time} using the set of parameters configured in this builder. The
  value will contain {@link #digits(int)} digits.
  
  @param time
  the time (in milliseconds)
  
  @return the Time-based One-time Password value as numeric String in base
  10 that includes {@link #digits(int)} digits.