Skip to content

Password Hygiene Guide

💡
Before you start

Python 3 and a terminal. No password of yours is typed, stored or sent anywhere. macOS and Linux include Python; on Windows install it from python.org with “Add python.exe to PATH” ticked, then check with python3 --version.

Do not put a real password of yours into any of these files. Everything here works on examples, and the point is to measure the shape of a password rather than test a particular one. Step 3 takes about ten seconds to run because it is deliberately doing expensive work; that is the finding, not a fault.

Why Passwords Matter

Your password is the first and often the only barrier between an attacker and your personal data. Email accounts, bank accounts, social media profiles, cloud storage -- all of it is protected by passwords. If an attacker obtains your password, they gain the same level of access that you have, and they can act as you.

The consequences of a compromised password go far beyond a single account. Attackers use stolen email credentials to reset passwords on other services, access private conversations, impersonate you to your contacts, and launch further attacks. A single weak or reused password can unravel your entire digital life.

💡
The Scale of Password Breaches

Billions of username and password combinations have been leaked in data breaches over the past decade. Attackers compile these into massive databases and use automated tools to try them against thousands of websites simultaneously. This technique, called credential stuffing, is why reusing passwords is so dangerous.

What Makes a Strong Password

A strong password resists both automated guessing attacks and human intuition. The two primary factors that determine password strength are length and unpredictability. A password that is long but predictable (such as "aaaaaaaaaaaaaaa") is weak. A password that is random but short (such as "k9$Qz") is also weak. You need both qualities working together.

Length Is More Important Than Complexity

A 20-character password made of lowercase letters is significantly harder to crack than an 8-character password with uppercase, lowercase, numbers, and symbols. This is because each additional character multiplies the number of possible combinations exponentially. Modern password cracking hardware can test billions of short passwords per second, but a sufficiently long password takes centuries to brute-force even with unlimited computing power.

Weak passwords (easily cracked):
  password123          -- Common word + simple numbers
  Summer2024!          -- Predictable pattern (Season + Year + Symbol)
  qwerty               -- Keyboard pattern
  john.smith1985       -- Personal information

Strong passwords (resist cracking):
  correct-horse-battery-staple     -- Long passphrase (4+ random words)
  tK8$mP2!vR4@nL9&wQ6              -- Long random string
  glacier.notebook.railway.cactus  -- Random words with separator
⚠️
Avoid personal information in passwords.

Names, birthdays, pet names, addresses, and phone numbers are the first things attackers try. This information is often publicly available on social media, public records, or previous data breaches. A password built from personal details is not a password -- it is a puzzle with publicly available pieces.

The Passphrase Technique

A passphrase is a password made of multiple random words strung together. Passphrases are both stronger and easier to remember than traditional complex passwords. The key is that the words must be truly random -- not a meaningful sentence, not a quote, and not something you would naturally say.

How to Create a Good Passphrase

The most secure method is to use a word list and a source of randomness. The Diceware method, for example, uses physical dice rolls to select words from a numbered list. Each word adds approximately 12.9 bits of entropy (randomness). A four-word passphrase provides about 51 bits of entropy, and a six-word passphrase provides about 77 bits -- strong enough for almost any purpose.

Generating a Diceware passphrase:

Roll five dice for each word. Look up the result in the Diceware word list.

  Roll: 4-1-6-2-3 --> Word: "mutual"
  Roll: 2-5-3-1-6 --> Word: "floss"
  Roll: 1-3-4-2-5 --> Word: "anvil"
  Roll: 6-2-1-4-3 --> Word: "timber"
  Roll: 3-5-1-6-2 --> Word: "kayak"

Passphrase: mutual-floss-anvil-timber-kayak

This is 64.6 bits of entropy -- strong enough for most accounts.
💡
Why Random Words, Not Sentences?

Natural language has patterns. If you use a grammatically correct sentence as a passphrase, attackers can exploit the predictable structure of language to dramatically reduce the number of guesses needed. "The cat sat on the mat" feels long but is far weaker than four truly random words because each word in a sentence constrains what can follow it.

Password Managers

A password manager is software that generates, stores, and fills in strong, unique passwords for every account you have. You remember one master password to unlock your password vault, and the manager handles everything else. This is the single most impactful step you can take to improve your password security.

Why You Need One

The average person has over 100 online accounts. It is humanly impossible to memorize a unique, strong password for each one. Without a password manager, people inevitably reuse passwords or use weak, memorable ones. A password manager eliminates this tradeoff entirely by removing the need to remember any password other than one master password.

Recommended Password Managers

  • KeePassXC -- Free, open-source, offline. Your vault is a local encrypted file that you control. No cloud sync unless you set it up yourself. Best for users who want full control.
  • Bitwarden -- Free tier available, open-source, cloud-synced. Can also be self-hosted. Good balance of convenience and transparency.
  • 1Password -- Paid, proprietary, cloud-synced. Polished user experience and good family/team sharing features.

How to Get Started

  • Install a password manager and create a strong master password (use the passphrase technique above)
  • Install the browser extension so it can auto-fill login forms
  • Start with your most critical accounts -- email, banking, and cloud storage
  • Generate a new unique password for each account as you log in to it
  • Over time, replace every reused password with a unique generated one
Your master password is the one password that matters.

Make it a strong passphrase of at least five random words. Memorize it thoroughly. Never write it down in a place that could be discovered. If you forget your master password, you may lose access to your entire vault, so consider storing an emergency copy in a sealed envelope in a secure physical location such as a safe or a safety deposit box.

One Unique Password Per Account

This is the most critical rule of password hygiene: never reuse a password across multiple accounts. Every single account should have its own unique, randomly generated password. No exceptions.

The reason is simple. Data breaches happen constantly, and they are outside your control. When a service gets breached and your password is exposed, attackers immediately try that same email and password combination on hundreds of other services. If you reused that password anywhere, those accounts are now compromised too.

How credential stuffing works:

1. Attacker obtains breach data:
     user@example.com : MyPassword123

2. Attacker runs automated tools against:
     - Gmail
     - Facebook
     - Amazon
     - Banking sites
     - Netflix
     - Every other major service

3. Any account using "MyPassword123" is compromised instantly.

If every account has a unique password, a breach on one
service affects only that one service.
⚠️
Slight variations do not count as unique.

Using "MyPassword1" for Gmail and "MyPassword2" for Facebook is not unique -- it is a pattern. Attackers know people do this and their tools account for it. A truly unique password is one that has no relationship whatsoever to any of your other passwords. Let your password manager generate random strings for you.

Checking for Breached Passwords

Even if you follow good practices now, passwords you used in the past may already be floating around in breach databases. The website Have I Been Pwned (haveibeenpwned.com) lets you check whether your email address or passwords have appeared in known breaches.

Checking Your Email

Visit haveibeenpwned.com and enter your email address. The site will tell you if your email appeared in any known data breaches and which services were involved. This does not mean your current passwords are compromised, but it tells you which accounts have had credentials exposed at some point.

Checking Your Passwords

Have I Been Pwned also offers a password checker at haveibeenpwned.com/Passwords. You can enter a password to see if it appears in any breach database. The check is done securely using a technique called k-anonymity -- your full password is never sent to the server. Only the first five characters of its hash are transmitted, and the matching is done locally on your device.

How the k-anonymity password check works:

1. Your password "example" is hashed with SHA-1:
     SHA-1("example") = C3499C2729730A7F807EFB8676A92DCB6F8A3F8F

2. Only the first 5 characters are sent to the server:
     Request: C3499

3. The server returns ALL hashes starting with C3499
     (typically 500-800 hashes)

4. Your browser checks locally if the full hash matches
     any in the returned list.

Your actual password never leaves your device.
💡
Many password managers integrate breach checking.

KeePassXC, Bitwarden, and 1Password all include features that automatically check your stored passwords against known breach databases. Enable this feature and review the results regularly. Any password that appears in a breach should be changed immediately, regardless of how strong it is.

Changing Compromised Passwords

When you discover that a password has been compromised -- whether through a breach notification, a Have I Been Pwned check, or suspicious account activity -- you need to act quickly and methodically.

  • Change the compromised password immediately -- Log in to the affected service and change the password to a new, unique, randomly generated one
  • Check for unauthorized changes -- Review account settings, recovery email addresses, connected apps, and recent activity for anything you did not do
  • Revoke active sessions -- Most services let you sign out of all devices. Do this to terminate any sessions the attacker may have open
  • Change the password everywhere you reused it -- If you used the same password on other accounts, change those too. Each one gets its own unique password
  • Enable two-factor authentication -- If the account supports 2FA and you have not enabled it, do so now. This adds a second layer that a stolen password alone cannot bypass
  • Watch for follow-up attacks -- Attackers who compromised one account may use the information they found to target you further through phishing or social engineering
⚠️
Prioritize your email account.

If your email password was compromised, treat it as the highest priority. Your email account is the master key to your digital life -- it receives password reset links for almost every other service you use. An attacker with access to your email can reset and take over all of your other accounts.

Crack Your Own Password Habits, in Five Steps

Password advice has been repeated so often that most people can recite it and almost nobody has seen the evidence behind it. That is a problem, because two of the most repeated rules — mix in symbols and numbers, change it every ninety days — turn out to be much weaker than they sound once you count properly. In the next twenty minutes you will count the real size of a password's haystack, crack P@ssw0rd123 on your own machine, measure the difference a website's choice of hash makes, and check a password against a breach list without revealing it. Every line of output below came from running these files.

1
Count the haystack twice: naively, then honestly

Go: open a terminal in a folder you can write to — cd ~/Desktop on macOS or Linux, cd %USERPROFILE%\Desktop on Windows.

Do: save this as space.py and run python3 space.py.

"""Two ways to count the haystack: naively, and the way an attacker counts."""
import math

GUESSES_PER_SEC = 10_000_000_000     # a rented GPU rig against a fast hash

def naive(pw):
    """Pretend every character was chosen at random from 95 printable ones."""
    return 95 ** len(pw)

def realistic(pw, structure):
    """Count the choices actually made, given how the password was built."""
    n = 1
    for count in structure:
        n *= count
    return n

CANDIDATES = [
    ("Tr0ub4dor&3", [100_000,      # a base word from a large word list
                     2 ** 9,       # which letters got leet-substituted
                     33 * 10]),    # one symbol and one digit on the end
    ("Summer2026!", [500,          # season/month/name
                     100,          # year
                     33]),         # trailing symbol
    ("correct horse battery staple", [7776] * 4),   # four words from a 7776-word list
]

def readable(seconds):
    for limit, unit, name in ((60, 1, "seconds"), (3600, 60, "minutes"),
                              (86400, 3600, "hours"), (86400 * 365, 86400, "days")):
        if seconds < limit:
            return "%.4g %s" % (seconds / unit, name)
    years = seconds / 86400 / 365
    return "%.4g years" % years if years < 1e6 else "%.2e years" % years

print("%-30s %-22s %s" % ("PASSWORD", "IF EVERY CHAR RANDOM", "AS AN ATTACKER COUNTS IT"))
print("-" * 88)
for pw, structure in CANDIDATES:
    n_naive, n_real = naive(pw), realistic(pw, structure)
    print("%-30s 2^%-4.1f %-15s 2^%-4.1f %s" % (
        pw, math.log2(n_naive), readable(n_naive / GUESSES_PER_SEC),
        math.log2(n_real), readable(n_real / GUESSES_PER_SEC)))

print()
ratio = realistic("x", [7776] * 4) / realistic("x", [100_000, 2 ** 9, 330])
print("passphrase vs Tr0ub4dor&3, attacker's count: %.0f times harder" % ratio)
print()
print("The first two columns are why people believe short mangled passwords")
print("are strong. The third column is what actually happens to them.")

You should see: the same passwords surviving eighteen thousand years or one second, depending on how you count:

PASSWORD                       IF EVERY CHAR RANDOM   AS AN ATTACKER COUNTS IT
----------------------------------------------------------------------------------------
Tr0ub4dor&3                    2^72.3 1.804e+04 years 2^34.0 1.69 seconds
Summer2026!                    2^72.3 1.804e+04 years 2^20.7 0.000165 seconds
correct horse battery staple   2^184.0 7.54e+37 years  2^51.7 4.232 days

passphrase vs Tr0ub4dor&3, attacker's count: 216392 times harder

The first two columns are why people believe short mangled passwords
are strong. The third column is what actually happens to them.

The middle column is the calculation password-strength meters do, and it is wrong for exactly one reason: it assumes the characters were chosen at random, when in fact they were chosen by a person applying a rule. Tr0ub4dor&3 is not eleven random characters; it is one word, plus a decision about which letters to substitute, plus a symbol and a digit. Count those choices and the space collapses from 2^72 to 2^34.

The right-hand column is what an attacker's software actually enumerates, which is why the last row wins despite looking less “complex”. Four words drawn at random from a list of 7,776 involve four genuinely independent choices, and there is no shortcut through them.

If not: OverflowError or a math domain error means one of the structure lists contains a zero — every entry must be the number of options at that position, so it is at least 1.

2
Crack a password everyone thinks is clever

Go: the same folder.

Do: save this as crack.py and run python3 crack.py. It builds candidates the way real cracking tools do: a word list, the five substitutions everybody makes, and the endings everybody adds.

"""A dictionary attack with the mangling rules everyone independently invents."""
import hashlib, itertools, time

WORDS = ["password", "summer", "dragon", "liverpool", "monkey", "welcome",
         "letmein", "trustno", "sunshine", "princess"]
SUBS = {"a": "@", "e": "3", "i": "1", "o": "0", "s": "$"}
SUFFIXES = [""] + [str(y) for y in range(1990, 2030)] + ["!", "1!", "123", "123!"]

def leets(word):
    options = [[c, SUBS[c]] if c in SUBS else [c] for c in word]
    return {"".join(p) for p in itertools.product(*options)}

def candidates():
    for w in WORDS:
        for base in leets(w):
            for cap in {base, base.capitalize()}:
                for suf in SUFFIXES:
                    yield cap + suf

TARGET = hashlib.sha256(b"P@ssw0rd123").hexdigest()

start = time.time()
tried = 0
for guess in candidates():
    tried += 1
    if hashlib.sha256(guess.encode()).hexdigest() == TARGET:
        print("cracked   :", guess)
        break
else:
    print("not found in", tried, "candidates")

print("guesses   :", format(tried, ","))
print("wordlist  :", len(WORDS), "words")
print("total space searched:", format(sum(1 for _ in candidates()), ","))
print()
print("Every substitution you thought made it clever is one of five rules")
print("that every cracking tool has had built in since the 1990s.")

You should see: the password found in under five hundred guesses:

cracked   : P@ssw0rd123
guesses   : 494
wordlist  : 10 words
total space searched: 8,190

Every substitution you thought made it clever is one of five rules
that every cracking tool has had built in since the 1990s.

Four hundred and ninety-four guesses, from a word list of ten. A real attacker starts with a list of several hundred million real passwords taken from previous breaches, ordered by how often people chose them, and applies thousands of rules rather than five.

This is the finding that should change a habit. The substitutions are not a secret you invented — they are so universal that they were built into cracking software before most people reading this had an email address. Replacing o with 0 multiplies the search by two, not by a thousand.

If not: if it prints not found, the target string and the candidate generator disagree about capitalisation — the target is P@ssw0rd123 with a capital P, and the generator produces capitalised forms via base.capitalize(). The guess count may differ slightly from the transcript because Python sets are unordered, so the winning candidate can be reached at a different position; the order of magnitude is what matters.

3
Measure what the website's choice of hash is worth

Go: the same folder.

Do: save this as hashspeed.py and run python3 hashspeed.py. It takes about ten seconds — most of that is the slow hash doing its job.

"""Why the site's choice of hash matters more than your password's cleverness."""
import hashlib, time

password = b"correct horse battery staple"
salt = b"a-random-salt-per-user"

def timed(label, fn, n):
    start = time.time()
    for _ in range(n):
        fn()
    elapsed = time.time() - start
    per_sec = n / elapsed
    print("%-34s %12s guesses/second on this machine" % (label, format(int(per_sec), ",")))
    return per_sec

fast = timed("sha256, unsalted", lambda: hashlib.sha256(password).digest(), 200_000)
slow = timed("scrypt, n=2^14 r=8 p=1", lambda: hashlib.scrypt(password, salt=salt, n=2**14, r=8, p=1), 20)

print()
print("ratio: the slow one is %s times more expensive per guess"
      % format(int(fast / slow), ","))
print()
space = 7776 ** 4                     # the four-word passphrase from step 1
for label, rate in (("sha256", fast), ("scrypt", slow)):
    days = space / rate / 86400
    print("four-word passphrase against %-8s %14.1f days" % (label + ":", days))
print()
print("Same password. The only thing that changed is what the site did with it.")

You should see: a difference of four or five orders of magnitude per guess:

sha256, unsalted                      1,842,322 guesses/second on this machine
scrypt, n=2^14 r=8 p=1                       22 guesses/second on this machine

ratio: the slow one is 80,514 times more expensive per guess

four-word passphrase against sha256:         22969.2 days
four-word passphrase against scrypt:    1849342119.6 days

Same password. The only thing that changed is what the site did with it.

Your numbers will differ from these and that is expected — the rates depend entirely on the processor you are using. What holds on any machine is the ratio, which is tens of thousands to one, and the consequence in the last two lines.

A password-hashing function such as scrypt, bcrypt or Argon2 is deliberately slow and deliberately memory-hungry, so that an attacker who steals the database cannot test billions of candidates per second. sha256 is a fine hash and a terrible password hash, because being fast is the whole of its design.

You cannot choose which one a website uses. What you can do is stop relying on their choice, which is what steps 4 and 5 are about.

If not: if scrypt raises a memory error, lower n to 2**12 — the parameters are chosen to consume real memory on purpose, and that is what makes it expensive to parallelise. The ratio will shrink accordingly, which is itself worth seeing.

4
Ask whether a password has leaked, without handing it over

Go: the same folder.

Do: save this as kanon.py and run python3 kanon.py.

"""How to ask 'has my password leaked?' without revealing the password."""
import hashlib

# Stand-in for a breach corpus. The real one holds hundreds of millions.
BREACHED = ["password", "123456", "qwerty", "P@ssw0rd123", "letmein",
            "monkey", "iloveyou", "dragon", "sunshine", "princess"]

INDEX = {}
for p in BREACHED:
    h = hashlib.sha1(p.encode()).hexdigest().upper()
    INDEX.setdefault(h[:5], []).append(h[5:])

def check(password):
    h = hashlib.sha1(password.encode()).hexdigest().upper()
    prefix, suffix = h[:5], h[5:]
    bucket = INDEX.get(prefix, [])          # <- ONLY the prefix is sent
    return prefix, len(bucket), suffix in bucket

for pw in ("P@ssw0rd123", "correct horse battery staple"):
    prefix, bucket_size, found = check(pw)
    print("password           :", pw)
    print("  sent to the server:", prefix, "(5 hex characters, nothing else)")
    print("  answers returned  :", bucket_size)
    print("  in a known breach :", "YES -- change it everywhere" if found else "not in this corpus")
    print()

print("The server sees 5 characters of a hash. It cannot tell which password")
print("you asked about, and cannot reverse them. You do the final comparison")
print("yourself, on your own machine.")

You should see: one password found in the corpus, having sent five characters:

password           : P@ssw0rd123
  sent to the server: 0F0D9 (5 hex characters, nothing else)
  answers returned  : 1
  in a known breach : YES -- change it everywhere

password           : correct horse battery staple
  sent to the server: ABF7A (5 hex characters, nothing else)
  answers returned  : 0
  in a known breach : not in this corpus

The server sees 5 characters of a hash. It cannot tell which password
you asked about, and cannot reverse them. You do the final comparison
yourself, on your own machine.

This is how the breach-checking services you may have used actually work, and it is worth knowing because the obvious objection — “why would I type my password into someone else's website?” — is a good one that the design answers. Your browser hashes the password locally, sends the first five characters of the hash, receives every hash in the corpus that begins with those five, and finishes the comparison on your machine. The server never sees enough to identify which password you asked about.

What a match means: that exact password appears in a published breach corpus, so it is already in the word lists attackers use, and its strength is now zero regardless of how it is constructed. Change it wherever it is used, starting with your email.

If not: if both passwords report not in this corpus, the strings in BREACHED lost a character; P@ssw0rd123 must match exactly. The prefixes shown are deterministic, so yours will be identical to these.

5
Measure what one leaked password costs you

Go: the same folder.

Do: save this as reuse.py and run python3 reuse.py.

"""One breach, and then what?"""

ACCOUNTS = {
    "old forum (breached 2019)": "sunshine88",
    "webmail":                   "sunshine88",
    "online banking":            "sunshine88!",
    "shopping site":             "sunshine88",
    "work login":                "Sunshine88",
}

leaked = "sunshine88"

def variants(p):
    return {p, p + "!", p.capitalize(), p.capitalize() + "!", p + "1", p + "123"}

tried = variants(leaked)
print("password leaked in the 2019 breach:", leaked)
print("variants an attacker tries         :", len(tried))
print()
for account, pw in ACCOUNTS.items():
    print("  %-28s %s" % (account, "OPENS" if pw in tried else "holds"))

opened = sum(1 for pw in ACCOUNTS.values() if pw in tried)
print()
print("accounts opened by one leaked password:", opened, "of", len(ACCOUNTS))
print()
print("Adding a '!' or a capital does not make a password different. It")
print("makes it the same password with one of six endings a script tries")
print("in the first second.")
print()
print("With unique passwords the same breach opens exactly 1 of 5 -- and")
print("that one is a forum you stopped using in 2019.")

You should see: a single 2019 leak opening every account:

password leaked in the 2019 breach: sunshine88
variants an attacker tries         : 6

  old forum (breached 2019)    OPENS
  webmail                      OPENS
  online banking               OPENS
  shopping site                OPENS
  work login                   OPENS

accounts opened by one leaked password: 5 of 5

Adding a '!' or a capital does not make a password different. It
makes it the same password with one of six endings a script tries
in the first second.

With unique passwords the same breach opens exactly 1 of 5 -- and
that one is a forum you stopped using in 2019.

Note which accounts fell to a variant rather than the exact string. Banking used sunshine88! and work used Sunshine88 — both felt like different passwords to the person choosing them, and neither survived a list of six obvious endings. This is called credential stuffing, it is automated, and it is why a breach at a forum you forgot about turns into a bank problem years later.

The single change worth making today is a password manager, because it makes uniqueness free. You stop choosing passwords, so they stop having patterns; every site gets a different random string; and one breach becomes one problem. The two passwords you still have to remember are the manager's own and your email account's, and both should be passphrases of four or more random words, as measured in step 1.

If not: if fewer accounts open, an entry in ACCOUNTS was changed — the point of the exercise is that all five are variants of one another. Adding a genuinely different password to the list is a worthwhile experiment: it will report holds.

🎉
Check yourself before moving on

Without scrolling up: your workplace requires passwords of at least twelve characters with an uppercase letter, a number and a symbol, changed every ninety days. A colleague says this is best practice. Which parts of it help, which part is counter-productive, and why? Answer: the length requirement helps, and it is the only part doing serious work — step 1 showed that independent choices are what enlarge the search space, and length is how you get them. The composition rules help far less than they appear to: forcing an uppercase letter and a symbol mostly produces a capital at the front and an exclamation mark at the end, which is one of the first patterns cracking software tries, as step 2 demonstrated in under five hundred guesses. The counter-productive part is the ninety-day expiry. People asked to change a password frequently do not invent a new one; they increment the old one, so Sunshine88! becomes Sunshine89! — and step 5 showed those variants are the same password as far as an attacker is concerned. It also encourages writing them down insecurely. Modern guidance, including NIST's, therefore recommends long passwords, screening against known-breached lists as in step 4, and forced changes only when there is evidence of compromise.

Now do it without the page: add your own habitual password shape to space.py — not the password, the structure: how many words or names you draw from, how many endings you use, how many substitutions. Count the choices honestly and see where it lands in the third column. Then do the part that actually helps: install a password manager, and move just three accounts into it — your email first, because every other account can be reset through it.

Summary

Good password hygiene is not about memorizing complicated strings. It is about using the right tools and habits so that every account is protected by a strong, unique password without relying on your memory.

  • Passwords are your primary defense -- a single compromised password can cascade into multiple account takeovers
  • Length beats complexity -- a long passphrase of random words is stronger and easier to remember than a short complex string
  • Use the Diceware method to generate truly random passphrases when you need to memorize a password
  • Use a password manager for everything else -- let it generate and store unique passwords for every account
  • Never reuse passwords -- not even with minor variations. One breach should only compromise one account
  • Check haveibeenpwned.com regularly to find out if your credentials have appeared in known breaches
  • Change compromised passwords immediately and revoke active sessions on affected accounts
🎉
Start today, not tomorrow.

You do not need to fix everything at once. Install a password manager today, secure your email account with a strong unique passphrase and two-factor authentication, then gradually work through your other accounts. Every password you update is one fewer vulnerability in your digital life.