Comparador de Textos

Compare dois textos lado a lado e destaque as diferenças linha por linha

Experimente um exemplo

Texto A

Texto B

Roda localmente · Seguro para colar segredos
Roda localmente · Seguro para colar segredos

O que é diff de texto?

Um diff de texto (abreviação de "difference", diferença) é o resultado da comparação de dois blocos de texto para identificar quais linhas foram adicionadas, removidas ou mantidas inalteradas. O conceito tem origem no utilitário diff do Unix, lançado pela primeira vez em 1974 como parte do Unix Versão 5. Hoje, o diff de texto é a base dos sistemas de controle de versão como o Git, onde cada commit armazena um diff em vez de uma cópia completa de cada arquivo.

Um algoritmo de diff encontra a Subsequência Comum Mais Longa (LCS, do inglês Longest Common Subsequence) entre duas sequências de linhas. As linhas presentes na LCS são marcadas como inalteradas. As linhas no texto original que não fazem parte da LCS são marcadas como removidas. As linhas no texto modificado que não fazem parte da LCS são marcadas como adicionadas. O resultado é o conjunto mínimo de alterações necessárias para transformar um texto no outro.

A saída do diff existe em vários formatos. O unified diff (padrão para git diff) prefixia linhas removidas com um sinal de menos e linhas adicionadas com um sinal de mais. O diff lado a lado organiza ambos os textos em colunas paralelas. Esta ferramenta usa comparação linha por linha com saída codificada por cores: verde para adições, vermelho para remoções e neutro para linhas inalteradas. As linhas inalteradas são exibidas sem prefixo por padrão, mas podem ser ocultadas para focar apenas no que mudou.

Por que usar um comparador de texto online?

Comparar texto no terminal exige instalar utilitários diff e lidar com flags de linha de comando. Uma ferramenta de diff no navegador elimina completamente esse atrito.

Comparação instantânea
Cole dois blocos de texto e veja as diferenças destacadas imediatamente. Sem criação de arquivos, sem comandos para lembrar, sem saída para interpretar.
🔒
Processamento com privacidade em primeiro lugar
Toda a comparação acontece no seu navegador usando JavaScript. Seu texto nunca sai do seu dispositivo, o que importa ao comparar arquivos de configuração, credenciais ou código proprietário.
📋
Saída pronta para copiar
A saída do diff usa os prefixos padrão + / - compatíveis com o formato unified diff. Você pode copiar o resultado diretamente em mensagens de commit, comentários de revisão de código ou relatórios de bug.
🌐
Sem cadastro ou instalação
Funciona em qualquer dispositivo com um navegador. Sem criação de conta, sem extensão, sem aplicativo desktop. Abra a página e comece a comparar.

Casos de uso do diff de texto

Desenvolvimento Frontend
Compare a saída minificada de CSS ou HTML antes e depois de uma etapa de build para identificar alterações não intencionais na marcação ou nos estilos gerados.
Engenharia Backend
Compare respostas de API entre ambientes (staging vs produção) para verificar se um deploy não introduziu alterações inesperadas nos dados.
DevOps e Infraestrutura
Compare manifestos Kubernetes, planos do Terraform ou configurações do Nginx antes de aplicar alterações a um cluster ou servidor em produção.
QA e Testes
Verifique se a saída de um teste corresponde às baselines esperadas comparando o resultado real com um arquivo de snapshot armazenado.
Engenharia de Dados
Compare cabeçalhos CSV ou definições de schema SQL entre migrações de banco de dados para confirmar se colunas foram adicionadas ou renomeadas corretamente.
Aprendizado e Estudos
Compare sua solução com uma implementação de referência linha por linha para identificar onde sua lógica diverge da abordagem esperada.

Comparação dos Formatos de Saída do Diff

Ferramentas de diff produzem saída em vários formatos. A tabela abaixo resume os mais comuns, o que os gera e quando cada um é útil.

FormatoFerramenta / OrigemDescrição
Unified diffdiff -u / git diffPrefixes lines with + / - / space; includes @@ hunk headers
Side-by-sidediff -y / sdiffTwo columns, changed lines aligned horizontally
Context diffdiff -cShows changed lines with surrounding context, marked with ! / + / -
HTML diffPython difflibColor-coded HTML table with inline change highlights
JSON PatchRFC 6902Array of add/remove/replace operations on a JSON document

Como o diff de linhas funciona: o algoritmo LCS

A maioria das ferramentas de diff de linhas, incluindo esta, usa o algoritmo LCS (Longest Common Subsequence — Subsequência Comum Mais Longa). O LCS encontra o maior conjunto de linhas que aparece nos dois textos na mesma ordem relativa, sem exigir que sejam contíguas. As linhas que não fazem parte da LCS são as diferenças reais.

O algoritmo LCS padrão usa programação dinâmica e executa em tempo O(m x n), onde m e n são os números de linhas dos dois textos. Para arquivos grandes, variantes otimizadas como o algoritmo de diff de Myers (usado pelo Git) reduzem isso para O(n + d²), onde d é o número de diferenças, tornando-o rápido quando a maioria das linhas é compartilhada.

1. Construir a tabela de PD
Crie uma matriz (m+1) x (n+1). Para cada par de linhas, armazene o comprimento da subsequência comum mais longa vista até aquele ponto. Linhas iguais estendem o valor diagonal em 1.
2. Fazer o backtrack
Percorra da célula inferior direita da matriz de volta a (0,0). Movimentos diagonais em linhas iguais produzem entradas "inalteradas". Movimentos horizontais ou verticais produzem entradas "adicionadas" ou "removidas".
3. Renderizar a saída
Mapeie cada entrada para uma linha de exibição: linhas inalteradas não recebem prefixo, linhas adicionadas recebem +, linhas removidas recebem -. Aplique codificação de cores para clareza visual.

Exemplos de Código

Implementações de comparação de texto linha por linha em JavaScript, Python, Go e na linha de comando. Cada exemplo produz saída no estilo unified diff.

JavaScript
// Line-by-line diff using the LCS algorithm
function diffLines(a, b) {
  const linesA = a.split('\n')
  const linesB = b.split('\n')

  // Build LCS table
  const m = linesA.length, n = linesB.length
  const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0))
  for (let i = 1; i <= m; i++)
    for (let j = 1; j <= n; j++)
      dp[i][j] = linesA[i-1] === linesB[j-1]
        ? dp[i-1][j-1] + 1
        : Math.max(dp[i-1][j], dp[i][j-1])

  // Backtrack to produce diff
  const result = []
  let i = m, j = n
  while (i > 0 || j > 0) {
    if (i > 0 && j > 0 && linesA[i-1] === linesB[j-1]) {
      result.unshift({ type: 'equal', text: linesA[i-1] }); i--; j--
    } else if (j > 0 && (i === 0 || dp[i][j-1] >= dp[i-1][j])) {
      result.unshift({ type: 'add', text: linesB[j-1] }); j--
    } else {
      result.unshift({ type: 'remove', text: linesA[i-1] }); i--
    }
  }
  return result
}

const diff = diffLines("alpha\nbeta\ngamma", "alpha\nbeta changed\ngamma\ndelta")
// → [
//   { type: 'equal',  text: 'alpha' },
//   { type: 'remove', text: 'beta' },
//   { type: 'add',    text: 'beta changed' },
//   { type: 'equal',  text: 'gamma' },
//   { type: 'add',    text: 'delta' }
// ]
Python
import difflib

text_a = """alpha
beta
gamma""".splitlines()

text_b = """alpha
beta changed
gamma
delta""".splitlines()

# Unified diff (same format as git diff)
for line in difflib.unified_diff(text_a, text_b, fromfile='a.txt', tofile='b.txt', lineterm=''):
    print(line)
# --- a.txt
# +++ b.txt
# @@ -1,3 +1,4 @@
#  alpha
# -beta
# +beta changed
#  gamma
# +delta

# HTML side-by-side diff
d = difflib.HtmlDiff()
html = d.make_file(text_a, text_b, fromdesc='Original', todesc='Modified')
Go
package main

import (
	"fmt"
	"strings"
)

// Minimal LCS-based line diff
func diffLines(a, b string) {
	la := strings.Split(a, "\n")
	lb := strings.Split(b, "\n")
	m, n := len(la), len(lb)

	dp := make([][]int, m+1)
	for i := range dp {
		dp[i] = make([]int, n+1)
	}
	for i := 1; i <= m; i++ {
		for j := 1; j <= n; j++ {
			if la[i-1] == lb[j-1] {
				dp[i][j] = dp[i-1][j-1] + 1
			} else if dp[i-1][j] >= dp[i][j-1] {
				dp[i][j] = dp[i-1][j]
			} else {
				dp[i][j] = dp[i][j-1]
			}
		}
	}

	var result []string
	i, j := m, n
	for i > 0 || j > 0 {
		if i > 0 && j > 0 && la[i-1] == lb[j-1] {
			result = append([]string{" " + la[i-1]}, result...)
			i--; j--
		} else if j > 0 && (i == 0 || dp[i][j-1] >= dp[i-1][j]) {
			result = append([]string{"+" + lb[j-1]}, result...)
			j--
		} else {
			result = append([]string{"-" + la[i-1]}, result...)
			i--
		}
	}

	for _, line := range result {
		fmt.Println(line)
	}
}

// Output:
//  alpha
// -beta
// +beta changed
//  gamma
// +delta
CLI (diff / git)
# Compare two files with unified diff (3 lines of context)
diff -u original.txt modified.txt

# Git diff between working tree and last commit
git diff HEAD -- file.txt

# Git diff between two branches
git diff main..feature -- src/

# Side-by-side diff in the terminal
diff -y --width=120 original.txt modified.txt

# Color-coded diff (requires colordiff)
diff -u original.txt modified.txt | colordiff

Perguntas Frequentes

Qual é a diferença entre diff de linhas e diff de caracteres?
Um diff de linhas compara o texto linha por linha: se qualquer caractere em uma linha mudar, a linha inteira é marcada como removida e a nova versão é marcada como adicionada. Um diff de caracteres (ou diff de palavras) opera em uma granularidade mais fina, marcando os caracteres ou palavras específicos que mudaram dentro de uma linha. O diff de linhas é padrão para revisão de código; o diff de caracteres é mais útil para edição de prosa.
Como o git diff funciona internamente?
O Git usa o algoritmo de diff de Myers por padrão, que encontra o script de edição mais curto (o número mínimo de inserções e exclusões) entre dois arquivos. O Git armazena o resultado no formato unified diff com cabeçalhos de bloco @@ que indicam os números de linha. Quando você executa git diff, o Git compara a árvore de trabalho com o índice (área de staging), não com o último commit, a menos que você passe HEAD explicitamente.
Posso comparar arquivos binários com uma ferramenta de diff de texto?
Não. Ferramentas de diff de texto dividem a entrada em caracteres de nova linha e comparam strings. Arquivos binários contêm sequências arbitrárias de bytes que produzem divisões de linha sem sentido. Para comparação binária, use uma ferramenta de hex diff ou uma comparação de checksum em nível de arquivo (sha256sum nos dois arquivos).
Meus dados são enviados a um servidor ao usar esta ferramenta?
Não. Esta ferramenta executa inteiramente no seu navegador. O cálculo do diff usa uma implementação LCS em JavaScript que é executada no lado do cliente. Nenhuma requisição de rede é feita com o conteúdo do seu texto. Você pode verificar isso abrindo a aba Rede do seu navegador enquanto usa a ferramenta.
O que é o formato unified diff?
O unified diff é o formato de saída usado por diff -u e git diff. Ele mostra linhas alteradas com prefixos - (removida) e + (adicionada), precedidos por cabeçalhos @@ que especificam os intervalos de números de linha nos dois arquivos. Linhas de contexto (inalteradas) têm um prefixo de espaço. O unified diff é o formato mais comum para patches, pull requests e ferramentas de revisão de código.
Como comparar arquivos grandes com muitas diferenças?
Para arquivos com milhares de linhas, uma ferramenta no navegador funciona, mas pode ficar lenta porque o algoritmo LCS escala de forma quadrática. Para diffs muito grandes, ferramentas de linha de comando como diff ou git diff são mais rápidas por usarem implementações otimizadas em C e poderem transmitir a saída. Você também pode filtrar as linhas inalteradas (desativando "Mostrar linhas inalteradas" nesta ferramenta) para focar apenas nas alterações.
O que é um diff de merge de três vias?
Um merge de três vias compara duas versões modificadas de um arquivo em relação ao seu ancestral comum (a base). O Git usa isso durante git merge e git rebase. Ele identifica as alterações feitas em cada branch em relação à base e as combina. Quando os dois branches modificam a mesma linha, o Git reporta um conflito de merge. O merge de três vias requer três entradas, enquanto um diff padrão precisa apenas de duas.