public static String generate(char[] password,byte[] salt,int cost){
  if (password == null) {
    throw new IllegalArgumentException("Password required.");
  }
  if (salt == null) {
    throw new IllegalArgumentException("Salt required.");
  }
 else   if (salt.length != 16) {
    throw new DataLengthException("16 byte salt required: " + salt.length);
  }
  if (cost < 4 || cost > 31) {
    throw new IllegalArgumentException("Invalid cost factor.");
  }
  byte[] psw=Strings.toUTF8ByteArray(password);
  byte[] tmp=new byte[psw.length >= 72 ? 72 : psw.length + 1];
  if (tmp.length > psw.length) {
    System.arraycopy(psw,0,tmp,0,psw.length);
  }
 else {
    System.arraycopy(psw,0,tmp,0,tmp.length);
  }
  Arrays.fill(psw,(byte)0);
  String rv=createBcryptString(tmp,salt,cost);
  Arrays.fill(tmp,(byte)0);
  return rv;
}

public static String generate ( char [ ] password , byte [ ] salt , int cost ) { if ( password == null ) { throw new IllegalArgumentException ( "Password required." ) ; } if ( salt == null ) { throw new IllegalArgumentException ( "Salt required." ) ; } else if ( salt . length != 16 ) { throw new DataLengthException ( "16 byte salt required: " + salt . length ) ; } if ( cost < 4 || cost > 31 ) { throw new IllegalArgumentException ( "Invalid cost factor." ) ; } byte [ ] psw = Strings . toUTF8ByteArray ( password ) ; byte [ ] tmp = new byte [ psw . length >= 72 ? 72 : psw . length + 1 ] ; if ( tmp . length > psw . length ) { System . arraycopy ( psw , 0 , tmp , 0 , psw . length ) ; } else { System . arraycopy ( psw , 0 , tmp , 0 , tmp . length ) ; } Arrays . fill ( psw , ( byte ) 0 ) ; String rv = createBcryptString ( tmp , salt , cost ) ; Arrays . fill ( tmp , ( byte ) 0 ) ; return rv ; }
creates a 60 character bcrypt string , including version , cost factor , salt and hash , separated by ' $ '
