Exemplo n.º 1
0
  /**
   * {@inheritDoc}
   *
   * <p><strong>Algorithm Description</strong>: if the lower bound is excluded, scales the output of
   * Random.nextDouble(), but rejects 0 values (i.e., will generate another random double if
   * Random.nextDouble() returns 0). This is necessary to provide a symmetric output interval (both
   * endpoints excluded).
   *
   * @throws NumberIsTooLargeException if {@code lower >= upper}
   * @throws NotFiniteNumberException if one of the bounds is infinite
   * @throws NotANumberException if one of the bounds is NaN
   */
  public double nextUniform(double lower, double upper, boolean lowerInclusive)
      throws NumberIsTooLargeException, NotFiniteNumberException, NotANumberException {

    if (lower >= upper) {
      throw new NumberIsTooLargeException(
          LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND, lower, upper, false);
    }

    if (Double.isInfinite(lower)) {
      throw new NotFiniteNumberException(LocalizedFormats.INFINITE_BOUND, lower);
    }
    if (Double.isInfinite(upper)) {
      throw new NotFiniteNumberException(LocalizedFormats.INFINITE_BOUND, upper);
    }

    if (Double.isNaN(lower) || Double.isNaN(upper)) {
      throw new NotANumberException();
    }

    final RandomGenerator generator = getRandomGenerator();

    // ensure nextDouble() isn't 0.0
    double u = generator.nextDouble();
    while (!lowerInclusive && u <= 0.0) {
      u = generator.nextDouble();
    }

    return u * upper + (1.0 - u) * lower;
  }
Exemplo n.º 2
0
 private void getVelocity() {
   vy = 3.0;
   vx = rgen.nextDouble(1.0, 3.0);
   if (rgen.nextBoolean(0.5)) {
     vx = -vx;
   }
 }
Exemplo n.º 3
0
 /**
  * Generate a random int value uniformly distributed between <code>lower</code> and <code>upper
  * </code>, inclusive.
  *
  * @param lower the lower bound.
  * @param upper the upper bound.
  * @return the random integer.
  */
 public int nextInt(int lower, int upper) {
   if (lower >= upper) {
     throw new IllegalArgumentException("upper bound must be > lower bound");
   }
   RandomGenerator rand = getRan();
   return lower + (int) (rand.nextDouble() * (upper - lower + 1));
 }
Exemplo n.º 4
0
 /**
  * Generate a random long value uniformly distributed between <code>lower</code> and <code>upper
  * </code>, inclusive.
  *
  * @param lower the lower bound.
  * @param upper the upper bound.
  * @return the random integer.
  */
 public long nextLong(long lower, long upper) {
   if (lower >= upper) {
     throw new IllegalArgumentException("upper bound must be > lower bound");
   }
   RandomGenerator rand = getRan();
   return lower + (long) (rand.nextDouble() * (upper - lower + 1));
 }
Exemplo n.º 5
0
 /**
  * Generate a random value from a Normal (a.k.a. Gaussian) distribution with the given mean,
  * <code>mu</code> and the given standard deviation, <code>sigma</code>.
  *
  * @param mu the mean of the distribution
  * @param sigma the standard deviation of the distribution
  * @return the random Normal value
  */
 public double nextGaussian(double mu, double sigma) {
   if (sigma <= 0) {
     throw new IllegalArgumentException("Gaussian std dev must be > 0");
   }
   RandomGenerator rand = getRan();
   return sigma * rand.nextGaussian() + mu;
 }
Exemplo n.º 6
0
  private void rotateTokens(HttpServletRequest request) {
    HttpSession session = request.getSession(true);

    /** rotate master token * */
    String tokenFromSession = null;

    try {
      tokenFromSession = RandomGenerator.generateRandomId(getPrng(), getTokenLength());
    } catch (Exception e) {
      throw new RuntimeException(
          String.format("unable to generate the random token - %s", e.getLocalizedMessage()), e);
    }

    session.setAttribute(getSessionKey(), tokenFromSession);

    /** rotate page token * */
    if (isTokenPerPageEnabled()) {
      @SuppressWarnings("unchecked")
      Map<String, String> pageTokens =
          (Map<String, String>) session.getAttribute(CsrfGuard.PAGE_TOKENS_KEY);

      try {
        pageTokens.put(
            request.getRequestURI(), RandomGenerator.generateRandomId(getPrng(), getTokenLength()));
      } catch (Exception e) {
        throw new RuntimeException(
            String.format("unable to generate the random token - %s", e.getLocalizedMessage()), e);
      }
    }
  }
Exemplo n.º 7
0
  /**
   * <strong>Algorithm Description:</strong> hex strings are generated using a 2-step process.
   *
   * <ol>
   *   <li>len/2+1 binary bytes are generated using the underlying Random
   *   <li>Each binary byte is translated into 2 hex digits
   * </ol>
   *
   * @param len the desired string length.
   * @return the random string.
   */
  public String nextHexString(int len) {
    if (len <= 0) {
      throw new IllegalArgumentException("length must be positive");
    }

    // Get a random number generator
    RandomGenerator ran = getRan();

    // Initialize output buffer
    StringBuffer outBuffer = new StringBuffer();

    // Get int(len/2)+1 random bytes
    byte[] randomBytes = new byte[(len / 2) + 1];
    ran.nextBytes(randomBytes);

    // Convert each byte to 2 hex digits
    for (int i = 0; i < randomBytes.length; i++) {
      Integer c = new Integer(randomBytes[i]);

      /* Add 128 to byte value to make interval 0-255 before
       * doing hex conversion.
       * This guarantees <= 2 hex digits from toHexString()
       * toHexString would otherwise add 2^32 to negative arguments.
       */
      String hex = Integer.toHexString(c.intValue() + 128);

      // Make sure we add 2 hex digits for each byte
      if (hex.length() == 1) {
        hex = "0" + hex;
      }
      outBuffer.append(hex);
    }
    return outBuffer.toString().substring(0, len);
  }
Exemplo n.º 8
0
 protected void setRandomValue(double a_value) {
   RandomGenerator randomGen = getGPConfiguration().getRandomGenerator();
   m_value_double = randomGen.nextDouble() * (m_upperBounds - m_lowerBounds) + m_lowerBounds;
   if (m_wholeNumbers) {
     m_value_double = Math.round(m_value_double);
   }
 }
  public Individual[] reproduce(Individual[] parents, GAParameterSet params) {
    if (parents.length != getRequiredNumberOfParents())
      throw new IllegalArgumentException(
          "Need "
              + getRequiredNumberOfParents()
              + " parents for reproduction (not "
              + parents.length
              + ")");

    // Check correct type for parents, get length:
    int bitLen = checkParentsTypeAndLength(parents);

    // Chance (1 - xover probability) that parents wont be changed:
    final RandomGenerator rnd = params.getRandomGenerator();

    if (rnd.nextDouble() >= getXOverProbability()) return makeCopyOfParents(parents, params);

    // Get parents bitsrings:
    BitString p1 = ((BinaryEncodedIndividual) parents[0]).getBitStringRepresentation();
    BitString p2 = ((BinaryEncodedIndividual) parents[1]).getBitStringRepresentation();

    // x-over:
    final int maxAttempts = params.getMaxBadReproductionAttempts();

    int attempts = 0;
    boolean kidsAreValid = false;
    do {
      kidsAreValid = false;
      int xPoint = rnd.nextInt(1, bitLen);

      // offspring bit strings:
      BitString c1 = new BitString(bitLen);
      BitString c2 = new BitString(bitLen);

      // copy before xover-point:
      for (int i = 0; i < xPoint; i++) {
        c1.set(i, p1.get(i));
        c2.set(i, p2.get(i));
      }

      // copy after xover-point:
      for (int i = xPoint; i < bitLen; i++) {
        c1.set(i, p2.get(i));
        c2.set(i, p1.get(i));
      }

      // create children and check if children are valid:
      ClassifierIndividual[] kids = createKidsFromEncoding(params, c1, c2);
      kidsAreValid = kidsSatisfyConstraints(kids, params);

      // return valid kids or have another attempts:
      if (kidsAreValid) return kids;
      else attempts++;

    } while (!kidsAreValid && attempts < maxAttempts);

    // all attempts failed:
    return makeCopyOfParents(parents, params);
  }
Exemplo n.º 10
0
 protected void setRandomValue(float a_value) {
   RandomGenerator randomGen = getGPConfiguration().getRandomGenerator();
   m_value_float =
       (float) (randomGen.nextFloat() * (m_upperBounds - m_lowerBounds) + m_lowerBounds);
   if (m_wholeNumbers) {
     m_value_float = Math.round(m_value_float);
   }
 }
Exemplo n.º 11
0
 public static byte[] RandomByteStringShort(RandomGenerator rand) {
   int x = rand.UniformInt(50);
   byte[] bytes = new byte[x];
   for (int i = 0; i < x; ++i) {
     bytes[i] = ((byte) rand.UniformInt(256));
   }
   return bytes;
 }
Exemplo n.º 12
0
 /** When mouse pressed: begin our fantastic game */
 public void mousePressed(MouseEvent e) {
   if (vx == 0) {
     vx = rgen.nextDouble(0.5, 1);
     vy = -1;
     if (rgen.nextBoolean() == true) {
       vx *= -1;
     }
   }
 }
Exemplo n.º 13
0
 /**
  * Returns a random value from an Exponential distribution with the given mean.
  *
  * <p><strong>Algorithm Description</strong>: Uses the <a
  * href="http://www.jesus.ox.ac.uk/~clifford/a5/chap1/node5.html">Inversion Method</a> to generate
  * exponentially distributed random values from uniform deviates.
  *
  * @param mean the mean of the distribution
  * @return the random Exponential value
  */
 public double nextExponential(double mean) {
   if (mean < 0.0) {
     throw new IllegalArgumentException("Exponential mean must be >= 0");
   }
   RandomGenerator rand = getRan();
   double unif = rand.nextDouble();
   while (unif == 0.0d) {
     unif = rand.nextDouble();
   }
   return -mean * Math.log(unif);
 }
Exemplo n.º 14
0
  private short generateWarehouseId() {
    short w_id = -1;

    // WAREHOUSE AFFINITY
    if (config.warehouse_affinity) {
      w_id = (short) this.affineWarehouse;
    }
    // TEMPORAL SKEW
    else if (config.temporal_skew) {
      if (generator.number(1, 100) <= config.temporal_skew_mix) {
        if (config.temporal_skew_rotate) {
          w_id =
              (short) ((this.tick_counter % parameters.warehouses) + parameters.starting_warehouse);
        } else {
          w_id = (short) config.first_warehouse;
        }
        this.temporal_counter++;
      } else {
        w_id = (short) generator.number(parameters.starting_warehouse, parameters.last_warehouse);
      }
    }
    // ZIPFIAN SKEWED WAREHOUSE ID
    else if (config.neworder_skew_warehouse) {
      assert (this.zipf != null);
      // w_id = (short)this.zipf.nextInt();
      w_id = (short) this.custom_skew.nextInt();
    }
    // GAUSSIAN SKEWED WAREHOUSE ID
    else if (skewFactor > 0.0d) {
      w_id =
          (short)
              generator.skewedNumber(
                  parameters.starting_warehouse, parameters.last_warehouse, skewFactor);
    }
    // UNIFORM DISTRIBUTION
    else {
      w_id = (short) generator.number(parameters.starting_warehouse, parameters.last_warehouse);
    }

    assert (w_id >= parameters.starting_warehouse)
        : String.format(
            "Invalid W_ID: %d [min=%d, max=%d]",
            w_id, parameters.starting_warehouse, parameters.last_warehouse);
    assert (w_id <= parameters.last_warehouse)
        : String.format(
            "Invalid W_ID: %d [min=%d, max=%d]",
            w_id, parameters.starting_warehouse, parameters.last_warehouse);

    this.lastWarehouseHistory.put(w_id);
    this.totalWarehouseHistory.put(w_id);

    return w_id;
  }
Exemplo n.º 15
0
 public static float RandomSingle(RandomGenerator rand, int exponent) {
   if (exponent == Integer.MAX_VALUE) {
     exponent = rand.UniformInt(255);
   }
   int r = rand.UniformInt(0x10000);
   if (rand.UniformInt(2) == 0) {
     r |= ((int) rand.UniformInt(0x10000)) << 16;
   }
   r &= ~0x7f800000; // clear exponent
   r |= ((int) exponent) << 23; // set exponent
   return Float.intBitsToFloat(r);
 }
Exemplo n.º 16
0
 private TPCCInputHandler() {
   super();
   // makeForRun requires the value cLast from the load generator in
   // order to produce a valid generator for the run. Thus the sort
   // of weird eat-your-own ctor pattern.
   RandomGenerator.NURandC base_loadC = new RandomGenerator.NURandC(0, 0, 0);
   RandomGenerator.NURandC base_runC =
       RandomGenerator.NURandC.makeForRun(new RandomGenerator.Implementation(0), base_loadC);
   RandomGenerator rng = new RandomGenerator.Implementation(0);
   rng.setC(base_runC);
   m_tpccSim =
       new TPCCSimulation(this, rng, new Clock.RealTime(), m_scaleParams, false, skewfactor);
 }
Exemplo n.º 17
0
  /**
   * <strong>Algorithm Description</strong>: scales the output of Random.nextDouble(), but rejects 0
   * values (i.e., will generate another random double if Random.nextDouble() returns 0). This is
   * necessary to provide a symmetric output interval (both endpoints excluded).
   *
   * @param lower the lower bound.
   * @param upper the upper bound.
   * @return a uniformly distributed random value from the interval (lower, upper)
   */
  public double nextUniform(double lower, double upper) {
    if (lower >= upper) {
      throw new IllegalArgumentException("lower bound must be <= upper bound");
    }
    RandomGenerator rand = getRan();

    // ensure nextDouble() isn't 0.0
    double u = rand.nextDouble();
    while (u <= 0.0) {
      u = rand.nextDouble();
    }

    return lower + u * (upper - lower);
  }
Exemplo n.º 18
0
 public static EInteger RandomSmallIntegral(RandomGenerator r) {
   int count = r.UniformInt(20) + 1;
   StringBuilder sb = new StringBuilder();
   if (r.UniformInt(2) == 0) {
     sb.append('-');
   }
   for (int i = 0; i < count; ++i) {
     if (i == 0) {
       sb.append((char) ('1' + r.UniformInt(9)));
     } else {
       sb.append((char) ('0' + r.UniformInt(10)));
     }
   }
   return EInteger.FromString(sb.toString());
 }
Exemplo n.º 19
0
 public static String RandomBigIntString(RandomGenerator r) {
   int count = r.UniformInt(400) + 1;
   StringBuilder sb = new StringBuilder();
   if (r.UniformInt(2) == 0) {
     sb.append('-');
   }
   for (int i = 0; i < count; ++i) {
     if (i == 0) {
       sb.append((char) ('1' + r.UniformInt(9)));
     } else {
       sb.append((char) ('0' + r.UniformInt(10)));
     }
   }
   return sb.toString();
 }
Exemplo n.º 20
0
 public static EFloat RandomEFloat(RandomGenerator r) {
   if (r.UniformInt(100) == 0) {
     int x = r.UniformInt(3);
     if (x == 0) {
       return EFloat.PositiveInfinity;
     }
     if (x == 1) {
       return EFloat.NegativeInfinity;
     }
     if (x == 2) {
       return EFloat.NaN;
     }
   }
   return EFloat.Create(RandomEInteger(r), EInteger.FromInt64(r.UniformInt(400) - 200));
 }
Exemplo n.º 21
0
  /**
   * {@inheritDoc}
   *
   * <p><strong>Algorithm Description:</strong> hex strings are generated in 40-byte segments using
   * a 3-step process.
   *
   * <ol>
   *   <li>20 random bytes are generated using the underlying <code>SecureRandom</code>.
   *   <li>SHA-1 hash is applied to yield a 20-byte binary digest.
   *   <li>Each byte of the binary digest is converted to 2 hex digits.
   * </ol>
   *
   * @throws NotStrictlyPositiveException if {@code len <= 0}
   */
  public String nextSecureHexString(int len) throws NotStrictlyPositiveException {
    if (len <= 0) {
      throw new NotStrictlyPositiveException(LocalizedFormats.LENGTH, len);
    }

    // Get SecureRandom and setup Digest provider
    final RandomGenerator secRan = getSecRan();
    MessageDigest alg = null;
    try {
      alg = MessageDigest.getInstance("SHA-1");
    } catch (NoSuchAlgorithmException ex) {
      // this should never happen
      throw new MathInternalError(ex);
    }
    alg.reset();

    // Compute number of iterations required (40 bytes each)
    int numIter = (len / 40) + 1;

    StringBuilder outBuffer = new StringBuilder();
    for (int iter = 1; iter < numIter + 1; iter++) {
      byte[] randomBytes = new byte[40];
      secRan.nextBytes(randomBytes);
      alg.update(randomBytes);

      // Compute hash -- will create 20-byte binary hash
      byte[] hash = alg.digest();

      // Loop over the hash, converting each byte to 2 hex digits
      for (int i = 0; i < hash.length; i++) {
        Integer c = Integer.valueOf(hash[i]);

        /*
         * Add 128 to byte value to make interval 0-255 This guarantees
         * <= 2 hex digits from toHexString() toHexString would
         * otherwise add 2^32 to negative arguments
         */
        String hex = Integer.toHexString(c.intValue() + 128);

        // Keep strings uniform length -- guarantees 40 bytes
        if (hex.length() == 1) {
          hex = "0" + hex;
        }
        outBuffer.append(hex);
      }
    }
    return outBuffer.toString().substring(0, len);
  }
Exemplo n.º 22
0
 /**
  * Returns the RandomGenerator used to generate non-secure random data.
  *
  * <p>Creates and initializes a default generator if null.
  *
  * @return the Random used to generate random data
  * @since 1.1
  */
 private RandomGenerator getRan() {
   if (rand == null) {
     rand = new JDKRandomGenerator();
     rand.setSeed(System.currentTimeMillis());
   }
   return rand;
 }
Exemplo n.º 23
0
  /** Executes a stock level transaction. */
  public void doStockLevel() throws IOException {
    int threshold =
        generator.number(
            TPCCConstants.MIN_STOCK_LEVEL_THRESHOLD, TPCCConstants.MAX_STOCK_LEVEL_THRESHOLD);

    client.callStockLevel(generateWarehouseId(), generateDistrict(), threshold);
  }
 /**
  * Operate on the given chromosome with the given mutation rate.
  *
  * @param a_chrom chromosome to operate
  * @param a_rate mutation rate
  * @param a_generator random generator to use (must not be null)
  * @return mutated chromosome of null if no mutation has occured.
  * @author Audrius Meskauskas
  * @author Florian Hafner
  * @since 3.3.2
  */
 protected IChromosome operate(
     final IChromosome a_chrom, final int a_rate, final RandomGenerator a_generator) {
   IChromosome chromosome = null;
   // ----------------------------------------
   for (int j = m_startOffset; j < a_chrom.size(); j++) {
     // Ensure probability of 1/currentRate for applying mutation.
     // ----------------------------------------------------------
     if (a_generator.nextInt(a_rate) == 0) {
       if (chromosome == null) {
         chromosome = (IChromosome) a_chrom.clone();
         // In case monitoring is active, support it.
         // -----------------------------------------
         if (m_monitorActive) {
           chromosome.setUniqueIDTemplate(a_chrom.getUniqueID(), 1);
         }
       }
       Gene[] genes = chromosome.getGenes();
       if (m_range == 0) {
         m_range = genes.length;
       }
       Gene[] mutated = operate(a_generator, j, genes);
       // setGenes is not required for this operator, but it may
       // be needed for the derived operators.
       // ------------------------------------------------------
       try {
         chromosome.setGenes(mutated);
       } catch (InvalidConfigurationException cex) {
         throw new Error("Gene type not allowed by constraint checker", cex);
       }
     }
   }
   return chromosome;
 }
Exemplo n.º 25
0
 /**
  * Returns the SecureRandom used to generate secure random data.
  *
  * <p>Creates and initializes if null. Uses {@code System.currentTimeMillis() +
  * System.identityHashCode(this)} as the default seed.
  *
  * @return the SecureRandom used to generate secure random data, wrapped in a {@link
  *     RandomGenerator}.
  */
 private RandomGenerator getSecRan() {
   if (secRand == null) {
     secRand = RandomGeneratorFactory.createRandomGenerator(new SecureRandom());
     secRand.setSeed(System.currentTimeMillis() + System.identityHashCode(this));
   }
   return secRand;
 }
Exemplo n.º 26
0
  /** getReady: Initialize the game */
  private void getReady() {

    // Make up the bricks
    double brickPerWidth =
        (getWidth() - DIST_BRICK_WALL * 2 - DIST_BRICK_BRICK * (NUM_BRICK_ROW - 1)) / NUM_BRICK_ROW;
    double brickPerHeight = BRICK_HEIGHT;
    double x_start = DIST_BRICK_WALL;
    double y_start;
    for (int i = 1; i <= NUM_BRICK_ROW; i++) {
      for (int j = 1; j <= NUM_BRICK_COL; j++) {
        y_start = 50 + (j - 1) * (DIST_BRICK_BRICK + brickPerHeight);
        GRect tmpbrick = new GRect(brickPerWidth, brickPerHeight);
        tmpbrick.setFilled(true);
        add(tmpbrick, x_start, y_start);
      }
      x_start += DIST_BRICK_BRICK + brickPerWidth;
    }

    // Make up the board
    board = new GRect(BOARD_WIDTH, BOARD_HEIGHT);
    board.setFilled(true);
    add(board, (getWidth() - BOARD_WIDTH) / 2, (getHeight() - 30));

    // Place the ball
    ball = new GOval(BALL_RADIUS * 2, BALL_RADIUS * 2);
    ball.setFilled(true);
    ball.setColor(Color.RED);
    add(ball, (getWidth() - BALL_RADIUS * 2) / 2, (getHeight() - 30 - BALL_RADIUS * 2));

    // Set up random generator
    rgen = RandomGenerator.getInstance();

    // Add Listeners
    addMouseListeners();
  }
public class RandomCircles extends GraphicsProgram {

  /** Number of circles */
  private static final int NCIRCLES = 10;

  /** Minimum radius */
  private static final double MIN_RADIUS = 5;

  /** Maximum radius */
  private static final double MAX_RADIUS = 50;

  public void run() {
    for (int i = 0; i < NCIRCLES; i++) {
      double r = rgen.nextDouble(MIN_RADIUS, MAX_RADIUS);
      double x = rgen.nextDouble(0, getWidth() - 2 * r);
      double y = rgen.nextDouble(0, getHeight() - 2 * r);
      GOval circle = new GOval(x, y, 2 * r, 2 * r);
      circle.setFilled(true);
      circle.setColor(rgen.nextColor());
      add(circle);
    }
  }

  /* Private instance variable */
  private RandomGenerator rgen = RandomGenerator.getInstance();
}
Exemplo n.º 28
0
 public void innerInitTopology() {
   RandomGenerator.randomDistinctSelection(tempIDsArray);
   int nodeNumber = getNodeNumber();
   for (int i = 0; i < nodeNumber; i++) {
     connectedIDsArray[tempIDsArray[i]] = tempIDsArray[(i + 1) % nodeNumber];
   }
 }
Exemplo n.º 29
0
  /**
   * Helper method of moved method.
   *
   * @param c receives array of adjacent cells.
   * @return Returns the cell where the herbivore will be move.
   */
  private Cell adjPlants(ArrayList<Cell> c) {

    Cell tempCell = null;
    ArrayList<Cell> emptyCells = new ArrayList<>();

    for (Cell fCells : c) {
      if (fCells.getComponentCount() > 0) {
        if (fCells.getComponents()[0] instanceof Plant) {

          // set life back to 5 (since herbivore had eaten)
          temp.life = 5;

          tempCell = fCells;

          return tempCell;
        }
      }
    }
    /*get a random adjacent cell if plants are not around
     * two herbivores cannot be in a same spot.
     */
    for (Cell fCells : c) {
      if (fCells.getComponentCount() == 0) {

        emptyCells.add(fCells);
      }
    }

    tempCell = emptyCells.get(RandomGenerator.nextNumber(emptyCells.size() - 1));

    return tempCell;
  }
Exemplo n.º 30
0
 public static String RandomTextString(RandomGenerator rand) {
   int length = rand.UniformInt(0x2000);
   StringBuilder sb = new StringBuilder();
   for (int i = 0; i < length; ++i) {
     int x = rand.UniformInt(100);
     if (x < 95) {
       // ASCII
       sb.append((char) (0x20 + rand.UniformInt(0x60)));
     } else if (x < 98) {
       // Supplementary character
       x = rand.UniformInt(0x400) + 0xd800;
       sb.append((char) x);
       x = rand.UniformInt(0x400) + 0xdc00;
       sb.append((char) x);
     } else {
       // BMP character
       x = 0x20 + rand.UniformInt(0xffe0);
       if (x >= 0xd800 && x < 0xe000) {
         // surrogate code unit, generate ASCII instead
         x = 0x20 + rand.UniformInt(0x60);
       }
       sb.append((char) x);
     }
   }
   return sb.toString();
 }