def _trim_and_hash(name):
    """Always-safe fallback for a DNS label

    Produces a valid and unique DNS label for any string

    - prefix with 'u-' to avoid collisions and first-character rules
    - Selects the first N characters that are safe ('x' if none are safe)
    - suffix with truncated hash of true name
    - length is guaranteed to be < 32 characters
      leaving room for additional components to build a DNS label.
      Will currently be between 12-19 characters:
        4 (prefix, delimiters) + 7 (hash) + 1-8 (name stub)
    """
    name_hash = hashlib.sha256(name.encode('utf8')).hexdigest()[:7]

    safe_chars = [c for c in name.lower() if c in _strict_dns_safe]
    name_stub = ''.join(safe_chars[:8])
    # We MUST NOT put the `--` in the 3rd and 4th position (RFC 5891)
    # which is reserved for IDNs
    # It would be if name_stub were empty, so put 'x' here
    # (value doesn't matter, as uniqueness is in the hash - the stub is more of a hint, anyway)
    if not name_stub:
        name_stub = "x"
    return f"u-{name_stub}--{name_hash}"
Always-safe fallback for a DNS label

Produces a valid and unique DNS label for any string

- prefix with 'u-' to avoid collisions and first-character rules
- Selects the first N characters that are safe ('x' if none are safe)
- suffix with truncated hash of true name
- length is guaranteed to be < 32 characters
leaving room for additional components to build a DNS label.
Will currently be between 12-19 characters:
4 (prefix, delimiters) + 7 (hash) + 1-8 (name stub)
jupyterhub/utils.py