public String generate(int length)
   {
      StringBuffer password = new StringBuffer(length);

      double pik = random.nextDouble(); // random number [0,1]
      long ranno = (long) (pik * sigma); // weight by sum of frequencies

      long sum = 0;
      for (int c1 = 0; c1 < 26; c1++)
         for (int c2 = 0; c2 < 26; c2++)
            for (int c3 = 0; c3 < 26; c3++)
            {
               sum += get(c1, c2, c3);
               if (sum > ranno)
               {
                  password.append(alphabet.charAt(c1));
                  password.append(alphabet.charAt(c2));
                  password.append(alphabet.charAt(c3));
                  c1 = 26; // Found start. Break all 3 loops.
                  c2 = 26;
                  c3 = 26;
               }
            }

      // Now do a random walk.
      int nchar = 3;
      while (nchar < length)
      {
         int c1 = alphabet.indexOf(password.charAt(nchar - 2));
         int c2 = alphabet.indexOf(password.charAt(nchar - 1));
         sum = 0;
         for (int c3 = 0; c3 < 26; c3++)
            sum += get(c1, c2, c3);

         if (sum == 0)
            break;

         pik = random.nextDouble();
         ranno = (long) (pik * sum);
         sum = 0;
         for (int c3 = 0; c3 < 26; c3++)
         {
            sum += get(c1, c2, c3);
            if (sum > ranno)
            {
               password.append(alphabet.charAt(c3));
               break;
            }
         }
         nchar++;
      }
      return password.toString();
   }