Dice coefficient similarity
night and nacht score 0.25: each word has 4 letter pairs and they share only ht. The Dice coefficient runs from 0 for no shared pairs to 1 for identical texts, a simple number for spotting near-duplicate names and titles. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Text a
- night
- Text b
- nacht
- Coefficient
- 0.25
- Percent
- 25
- Bigrams a
- 4
- Bigrams b
- 4
The Sørensen–Dice coefficient is a classic set-overlap measure that maps cleanly onto strings when each string is represented as its multiset of character bigrams—every adjacent pair of characters from left to right. Unlike edit distance, which counts insertions and deletions, Dice reports a bounded similarity in the closed interval from zero to one, so you can set thresholds without rescaling per string length. This capability accepts two texts, optionally folds case, builds bigram multisets, and returns the coefficient together with bigram counts and shared-pair tallies. Identical strings always score one; a string shorter than two characters against a different partner scores zero because no bigrams exist to overlap.
What the character-bigram Dice coefficient measures
Sørensen–Dice was defined for finite sets as twice the size of the intersection divided by the sum of the set sizes. For fuzzy string comparison the natural tokens are character bigrams: for a string of length n you form the n minus one ordered pairs of consecutive characters, counting duplicates when the same pair repeats. That multiset view matters for strings with repeated letters or rhythmic patterns, because a shared pair can contribute only up to the minimum of its counts in each text.
The formula is therefore dice equals two times the multiset intersection size, divided by the sum of the two bigram counts. A score of one means the two multiset bags are identical in the bigram sense—which holds whenever the normalized strings are equal. A score of zero means they share no adjacent pair at all, which is common for short unrelated words.
Values in between quantify partial overlap: night versus nacht shares the pair ht once among four bigrams on each side after lengths are accounted for, producing a mid-range coefficient rather than a binary match. Because the measure is symmetric and scale-free in the sense that both numerator and denominator grow with string length, it is widely used for record linkage, typo-tolerant search, and near-duplicate detection where you need a single comparable number without training a model.
Where Dice similarity earns its keep in products and pipelines
Product search and catalog hygiene use a Dice coefficient calculator to flag near-duplicate titles that differ by a swapped word or a missing letter without standing up embeddings. Customer-support tools compare free-text ticket subjects to a known template bank and route high-score hits to macros. Data-cleaning jobs in CRM and logistics match city names, SKUs, and person names across systems that disagree on capitalization or diacritics when case folding is enabled.
Failed validation does not consume balance. Keep strings modest for interactive use, pin coefficient in tests to twelve decimals, and you get reproducible fuzzy scores for homework demos, LMS plugins, and edge workers without importing a full fuzzy-matching library of your own.
What you can do with it
Near-duplicate title and SKU checks
Score product titles or catalog SKUs against each other with character-bigram Dice and flag pairs above a chosen threshold before merge or publish.
Typo-tolerant search and autocomplete
Rank query strings against a dictionary or recent searches using a 0–1 Dice score so near misses surface without edit-distance tuning per length.
Record linkage and CRM cleanup
Compare names, cities, or free-text fields across imports with optional case folding to cluster fuzzy matches before human review.
FAQ
What is the Sørensen–Dice coefficient for strings?
It is 2 times the multiset intersection of character bigrams divided by the sum of both bigram counts. The result is a similarity score between 0 and 1 for fuzzy string comparison.
What score do identical or empty strings get?
Identical strings (after optional case fold) always return coefficient 1. Two empty strings are identical and score 1; empty versus non-empty scores 0.
Is this the same as semantic text similarity?
No. This capability uses character bigrams only—it does not embed meaning. For meaning-based closeness use a semantic similarity tool; for fuzzy spelling and surface form, Dice is the right tool.
How is the Dice score calculated?
Twice the number of shared letter pairs, divided by the total pairs of both texts. Night and nacht have 4 pairs each and share one, ht, so the score is 2 divided by 8, which is 0.25.
Does capitalization change the score?
By default it does, so Night and night are not identical. Turn off case sensitivity and both texts are lowercased before the pairs are compared, which makes Night and night score 1.
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/str/dice-coefficient \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"text_a":"night","text_b":"nacht"}'const res = await fetch("https://api.kit.forhosting.com/str/dice-coefficient", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"text_a": "night",
"text_b": "nacht"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/str/dice-coefficient",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"text_a": "night",
"text_b": "nacht"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/str/dice-coefficient", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"text_a":"night","text_b":"nacht"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"text_a":"night","text_b":"nacht"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/str/dice-coefficient", 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_a": "night",
"text_b": "nacht"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "str.dice_coefficient",
"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
Input contract, options, and response shape
Either string may be empty; empty versus empty is treated as identical and returns coefficient one, while empty versus non-empty returns zero. POST a JSON body with two required string fields: text_a and text_b (aliases a, b, string_a, string_b, left, right, s1, s2, first, and second are accepted by the same pure solver). Optional case_sensitive defaults to true so Night and night differ; set it to false to lowercase both sides with the language-standard toLowerCase before bigram extraction. Non-string values for text_a or text_b, nulls, and a non-boolean case_sensitive raise invalid_input and are not billed. On success the body echoes text_a, text_b, and case_sensitive; coefficient is the Dice score rounded to twelve decimal places for stable goldens; percent is coefficient times one hundred with six fractional digits for display; bigrams_a and bigrams_b are the multiset sizes (length minus one when length is at least one); shared_bigrams is the multiset intersection size used in the numerator; and formula restates the identity in plain ASCII. Pair the coefficient with your own threshold—for example require coefficient greater than or equal to zero point eight for a soft match—because the API never invents a business rule about pass or fail. There is no network fetch, language model, or random seed: the same inputs always produce the same payload in the free browser path and on the edge Worker.
Technical questions
How do I call the Dice coefficient similarity API?
Send JSON with text_a and text_b (or aliases a and b). Optionally set case_sensitive to false. The response includes coefficient, percent, bigram counts, and shared_bigrams.
What does the Dice coefficient calculator cost?
The browser tool is free. API requests use prepaid KIT balance at $0.002 per successful call; invalid input is not billed.