FNV-1a hash
Get the FNV-1a fingerprint of any text, mixing in each byte before multiplying: foobar gives bf9cf968 at 32 bits, or sixteen hex digits at 64 bits, a stable tag for hash tables, bloom filters and cache keys. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text
- foobar
- Bits
- 32
- Bits
- 32
- Hash
- bf9cf968
- Hash int
- 3,214,735,720
- Bytes
- 6
FNV-1a is the alternate Fowler–Noll–Vo hash: a fast non-cryptographic digest built from a fixed offset basis, a carefully chosen prime, and a per-byte exclusive-or-then-multiply step that is popular in hash tables, bloom filters, and compact fingerprint fields. Developers reach for FNV-1a when they need a stable thirty-two or sixty-four bit tag that is cheaper than a cryptographic hash and more order-sensitive than a plain sum. This FNV-1a hash tool accepts plain text, serializes it as UTF-8, and returns a lowercase hexadecimal string—eight digits for the thirty-two bit profile or sixteen digits for the sixty-four bit profile—plus an integer form, the UTF-8 byte length, the chosen width, and an empty flag when the source string has zero length.
What FNV-1a means and how the 32 and 64 bit profiles differ
Fowler–Noll–Vo hashes fold a message into a fixed-width residual by starting from a documented offset basis and, for each input byte, first exclusive-oring the byte into the running hash and then multiplying by a prime chosen for that width. The alternate form FNV-1a applies the exclusive-or before the multiply; the older FNV-1 form multiplies first. This capability implements only FNV-1a because that order is the one most language ecosystems and hash-table tutorials quote today.
For thirty-two bits the offset basis is zero-x-eight-one-one-c-nine-d-c-five and the prime is zero-x-zero-one-zero-zero-zero-one-nine-three, producing an eight-digit lowercase hex string. For sixty-four bits the offset basis is zero-x-c-b-f-two-nine-c-e-four-eight-four-two-two-two-three-two-five and the prime is zero-x-one-zero-zero-zero-zero-zero-zero-zero-one-b-three, producing sixteen hex digits. FNV-1a is designed for fast hashing in tables and lightweight integrity tags; it is not a cryptographic hash and must not be used where deliberate collision resistance, password storage, or signature schemes are required.
If a third-party tool disagrees on the same UTF-8 bytes, it is almost always using FNV-1 instead of FNV-1a, a different width, or hashing UTF-16 code units instead of UTF-8 bytes.
What you can do with it
Hash-table keys and bucket tags
Compute FNV-1a of short strings when you need a stable 32 or 64 bit non-cryptographic fingerprint for table buckets, bloom filters, or cache shard keys.
Classroom and support demos
Show students and operators how editing a few characters changes the FNV-1a hex without installing local utilities or cryptographic libraries.
FAQ
What is the difference between 32-bit and 64-bit FNV-1a?
Both use the FNV-1a xor-then-multiply step on each UTF-8 byte, but with different offset bases and primes. Thirty-two bit returns eight hex digits; sixty-four bit returns sixteen. Default is 32 when bits is omitted.
What happens with empty input?
Empty text is valid. The response sets empty to true, hash to the offset basis for the chosen width (811c9dc5 for 32-bit, cbf29ce484222325 for 64-bit), and bytes to 0.
Is FNV-1a a cryptographic hash?
No. FNV-1a is a fast non-cryptographic hash for tables and lightweight fingerprints. Do not use it for passwords, signatures, or collision-resistant integrity against attackers; use SHA-family digests for those cases.
Why does another tool give a different FNV-1a hash?
On the same text, the other tool is almost always using FNV-1, which multiplies before mixing, a different width, or the text's UTF-16 code units instead of its UTF-8 bytes. This tool hashes UTF-8 bytes in the FNV-1a order.
How is an FNV-1a hash calculated?
It starts from a fixed offset basis, 0x811c9dc5 at 32 bits. For each byte of the text, the byte is first mixed into the running value with an exclusive or, then the value is multiplied by the prime 0x01000193 and kept to 32 bits.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/fnv1a \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text":"foobar"}'const res = await fetch("https://api.kit.forhosting.com/enc/fnv1a", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text": "foobar"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/fnv1a",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text": "foobar"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/fnv1a", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text":"foobar"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text":"foobar"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/fnv1a", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"text": "foobar"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.fnv1a",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
No network call, no random salt, and no wall clock enter the computation—every successful path is pure arithmetic at the published $0.002 base price.
What FNV-1a means and how the 32 and 64 bit profiles differ
Empty input leaves the residual equal to the offset basis itself, which this endpoint reports with empty set to true so clients can distinguish a deliberate blank from a missing field.
Input contract, response fields, and empty input behaviour
Empty string is allowed on purpose: the mathematical identity of FNV-1a on zero bytes is the offset basis, and pipelines that fingerprint optional fields need a stable residual instead of a hard failure. When the source length is zero the response sets empty to true, hash to the offset basis hex for the chosen width, and bytes to zero. There is no mode switch for FNV-1, MD5, SHA, or CRC: if you need those digests, use a dedicated capability so each landing page matches a single search intent and SEO slug. POST a JSON body with the required field text set to the string you want to hash. Aliases input, value, s, string, and content are accepted so older forms and short clients still bind. Optional bits selects the width: thirty-two (default) or sixty-four; aliases width and bit_width are accepted, and both numeric and string forms work. Finite numbers and big integers are stringified before hashing; objects, arrays, booleans, null, Infinity, and NaN raise invalid_input and are not billed. For non-empty input empty is false, bytes equals the UTF-8 length, hash is the lowercase hex digest without a zero-x prefix, and hash_int carries the same value as an unsigned integer for thirty-two bits or as a decimal string for sixty-four bits so full unsigned range stays exact in JSON. Algorithm is always the label FNV-1a; offset_basis and prime echo the parameter strings for the selected width so OpenAPI examples and support replies can quote the profile without ambiguity.
Where an FNV-1a hash API earns its keep
Developers paste short keys, configuration fragments, and cache identifiers into an FNV-1a hash calculator when they need a compact thirty-two or sixty-four bit bucket index that matches a language runtime or a legacy protocol note. Support engineers recompute digests from ticket text to confirm that a pasted dump was not truncated or re-encoded in transit. Education labs use the same endpoint to show that changing a single character flips many hex digits, illustrating avalanche behaviour without introducing cryptographic machinery. Keep payloads under the documented character ceiling, treat the hex field as the canonical paste target, and you get reproducible FNV-1a values for docs, SDKs, edge workers, and classroom demos without standing up a separate hashing service.
Integration use cases
CI golden vectors and empty-input fixtures
Pin foobar → bf9cf968 (32-bit) and empty → offset basis so continuous integration catches FNV-1 vs FNV-1a or UTF-8 encoding drift immediately.
Technical questions
How do I compute an FNV-1a hash of text?
Send JSON with text set to your string and optional bits of 32 or 64 (default 32). The hash field returns lowercase hex for the FNV-1a digest over UTF-8 bytes; hash_int is the same value as an unsigned integer (number for 32-bit, decimal string for 64-bit).
What does the FNV-1a hash calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.