@Override
    public String formatToCryptString() {
        // expected:
        // $argon2i$v=19$m=4096,t=3,p=4$M3ByeyZKLjFRREJqQi87WQ$5kRCtDjL6RoIWGq9bL27DkFNunucg1hW280PmP0XDtY
        Encoder encoder = java.util.Base64.getEncoder().withoutPadding();
        String saltBase64 = encoder.encodeToString(this.getSalt().getBytes());
        String dataBase64 = encoder.encodeToString(this.getBytes());

        return new StringJoiner("$", "$", "")
                .add(this.getAlgorithmName())
                .add("v=" + this.argonVersion)
                .add(formatParameters())
                .add(saltBase64)
                .add(dataBase64)
                .toString();
    }
128 bits of salt is the recommended salt length, taken from draft-irtf-cfrg-argon2-13, 4.2.
crypto/support/hashes/argon2/src/main/java/org/apache/shiro/crypto/support/hashes/argon2/Argon2Hash.java