public static String hashpw(String password, String salt) {
        BCrypt       B;
        String       real_salt;
        byte         passwordb[], saltb[], hashed[];
        char         minor       = (char) 0;
        int          rounds, off = 0;
        StringBuffer rs          = new StringBuffer();

        if (salt.charAt(0) != '$' || salt.charAt(1) != '2')
            throw new IllegalArgumentException("Invalid salt version");
        if (salt.charAt(2) == '$')
            off = 3;
        else {
            minor = salt.charAt(2);
            if (minor != 'a' || salt.charAt(3) != '$')
                throw new IllegalArgumentException("Invalid salt revision");
            off = 4;
        }

        // Extract number of rounds
        if (salt.charAt(off + 2) > '$')
            throw new IllegalArgumentException("Missing salt rounds");
        rounds = Integer.parseInt(salt.substring(off, off + 2));

        real_salt = salt.substring(off + 3, off + 25);
        try {
            passwordb = (password + (minor >= 'a' ? "\000" : "")).getBytes("UTF-8");
        } catch (UnsupportedEncodingException uee) {
            throw new AssertionError("UTF-8 is not supported");
        }

        saltb = decode_base64(real_salt, BCRYPT_SALT_LEN);

        B = new BCrypt();
        hashed = B.crypt_raw(passwordb, saltb, rounds,
                (int[]) bf_crypt_ciphertext.clone());

        rs.append("$2");
        if (minor >= 'a')
            rs.append(minor);
        rs.append("$");
        if (rounds < 10)
            rs.append("0");
        if (rounds > 30) {
            throw new IllegalArgumentException(
                    "rounds exceeds maximum (30)");
        }
        rs.append(Integer.toString(rounds));
        rs.append("$");
        rs.append(encode_base64(saltb, saltb.length));
        rs.append(encode_base64(hashed,
                bf_crypt_ciphertext.length * 4 - 1));
        return rs.toString();
    }
@Test
    public void testHashpw() {
        System.out.print("BCrypt.hashpw(): ");
        for (int i = 0; i < test_vectors.length; i++) {
            String plain    = test_vectors[i][0];
            String salt     = test_vectors[i][1];
            String expected = test_vectors[i][2];
            String hashed   = BCrypt.hashpw(plain, salt);
            Assert.assertEquals(hashed, expected);
            System.out.print(".");
        }
        System.out.println("");
    }