##### SUMMARY

I'm currently using ansible 2.9.9 (latest available on debian testing), with python 3.8.5
I used a playbook developed with ansible 2.7.7 (latest on debian stable), and I've been kick out of all my servers because the salt used in the password_hash() function contains specials caracters.

I dont know if this is intentional, an element missing in the documentation or if I was simply not aware of that fact, in any case, I think that it could be interessting to warn other about this.

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
User (password_hash)

##### ANSIBLE VERSION
2.9.9

##### STEPS TO REPRODUCE
```---
- name:
  hosts:
    - localhost
  gather_facts: false
  tasks:
    - debug:
        msg: "{{ 'password' | password_hash( 'sha512', 65534 | random( seed=inventory_hostname ) | string ) }}"
        
    - debug:
        msg: "{{ 'password' | password_hash( 'sha512', 'salt' ) }}"
        
    - debug:
        msg: "{{ 'password' | password_hash( 'sha512', 'salt-' ) }}"
        
    - debug:
        msg: "{{ 'password' | password_hash( 'sha512', 'salt_' ) }}"
```

##### ACTUAL RESULTS
```
[WARNING]: Unable to parse /home/.../ansible/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [localhost] *******************************************************************************************************************************************

TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => {
    "msg": "$6$43927$59/6eFzcpI0IigUdbYePA2OeIEwIkyqe9VJzYswDQhl6cD7I4SoZehr004rG.k4xB8/C5F7A4k9dU5LC1RdGn."
}

TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => {
    "msg": "$6$salt$IxDD3jeSOb5eB1CX5LBsqZFVkJdido3OUILO5Ifz5iwMuTS4XMS130MTSuDDl3aCI6WouIL9AjRbLCelDCy.g."
}

TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => {
    "msg": "*0"
}

TASK [debug] ***********************************************************************************************************************************************
ok: [localhost] => {
    "msg": "*0"
}

PLAY RECAP *************************************************************************************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
```

##### EXPECTED RESULTS
Not "*0" for the password hashed.

"""Format the password and salt for saving
    :arg password: the plaintext password to save
    :arg salt: the salt to use when encrypting a password
    :arg encrypt: Which method the user requests that this password is encrypted.
        Note that the password is saved in clear.  Encrypt just tells us if we
        must save the salt value for idempotence.  Defaults to None.
    :returns: a text string containing the formatted information
    .. warning:: Passwords are saved in clear.  This is because the playbooks
        expect to get cleartext passwords from this lookup.
    """
    if not encrypt and not salt:
        return password
    
    if not salt:
        raise AnsibleAssertionError('_format_content was called with encryption requested but no salt value')
    return u'%s salt=%s' % (password, salt)
def _write_password_file(b_path, content):
    b_pathdir = os.path.dirname(b_path)
    makedirs_safe(b_pathdir, mode=0o700)
    with open(b_path, 'wb') as f:
        os.chmod(b_path, 0o600)
        b_content = to_bytes(content, errors='surrogate_or_strict') + b'\n'
        f.write(b_content)
def _get_lock(b_path):