---
title: "Como Calcular Hashes SHA256 e MD5 em Zig"
url: "https://ziglang.com.br/receitas/como-calcular-hashes-sha256-e-md5-em-zig/"
markdown_url: "https://ziglang.com.br/receitas/como-calcular-hashes-sha256-e-md5-em-zig.MD"
description: "Aprenda a calcular hashes SHA256, MD5 e outros em Zig usando std.crypto.hash. Exemplos com strings, arquivos e verificação de integridade."
date: "2026-02-21"
author: "Zig Brasil"
---

# Como Calcular Hashes SHA256 e MD5 em Zig

Aprenda a calcular hashes SHA256, MD5 e outros em Zig usando std.crypto.hash. Exemplos com strings, arquivos e verificação de integridade.


## Introdução

Funções de hash criptográficas transformam dados de qualquer tamanho em uma sequência de bytes de tamanho fixo. São usadas para verificação de integridade, armazenamento de senhas, assinaturas digitais e deduplicação. Zig oferece implementações de SHA-256, SHA-512, MD5 e outros na biblioteca padrão via `std.crypto.hash`.

Nesta receita, você aprenderá a calcular hashes dos tipos mais comuns.

## Pré-requisitos

- Zig instalado (versão 0.13+). Veja o [guia de instalação](/tutoriais/como-instalar-zig/)
- Conhecimento básico de Zig. Consulte a [introdução ao Zig](/tutoriais/introducao-ao-zig/)

## SHA-256 Básico

```zig
const std = @import("std");
const Sha256 = std.crypto.hash.sha2.Sha256;

pub fn main() !void {
    const texto = "Olá, Zig Brasil!";

    // Calcular hash
    var hash: [Sha256.digest_length]u8 = undefined;
    Sha256.hash(texto, &hash, .{});

    // Exibir em hexadecimal
    std.debug.print("Texto: {s}\n", .{texto});
    std.debug.print("SHA-256: {s}\n", .{std.fmt.fmtSliceHexLower(&hash)});
}
```

## MD5

```zig
const std = @import("std");
const Md5 = std.crypto.hash.Md5;

pub fn main() !void {
    const texto = "Olá, Zig Brasil!";

    var hash: [Md5.digest_length]u8 = undefined;
    Md5.hash(texto, &hash, .{});

    std.debug.print("Texto: {s}\n", .{texto});
    std.debug.print("MD5: {s}\n", .{std.fmt.fmtSliceHexLower(&hash)});
    std.debug.print("Tamanho do digest: {d} bytes ({d} bits)\n", .{ hash.len, hash.len * 8 });
}
```

## Múltiplos Algoritmos

```zig
const std = @import("std");

pub fn main() !void {
    const texto = "Zig é incrível!";

    // SHA-256
    var sha256: [std.crypto.hash.sha2.Sha256.digest_length]u8 = undefined;
    std.crypto.hash.sha2.Sha256.hash(texto, &sha256, .{});

    // SHA-512
    var sha512: [std.crypto.hash.sha2.Sha512.digest_length]u8 = undefined;
    std.crypto.hash.sha2.Sha512.hash(texto, &sha512, .{});

    // MD5
    var md5: [std.crypto.hash.Md5.digest_length]u8 = undefined;
    std.crypto.hash.Md5.hash(texto, &md5, .{});

    std.debug.print("Texto: {s}\n\n", .{texto});
    std.debug.print("MD5:    {s}\n", .{std.fmt.fmtSliceHexLower(&md5)});
    std.debug.print("        ({d} bits)\n\n", .{md5.len * 8});
    std.debug.print("SHA256: {s}\n", .{std.fmt.fmtSliceHexLower(&sha256)});
    std.debug.print("        ({d} bits)\n\n", .{sha256.len * 8});
    std.debug.print("SHA512: {s}\n", .{std.fmt.fmtSliceHexLower(&sha512)});
    std.debug.print("        ({d} bits)\n", .{sha512.len * 8});
}
```

## Hash Incremental (Streaming)

Para dados que chegam em partes:

```zig
const std = @import("std");
const Sha256 = std.crypto.hash.sha2.Sha256;

pub fn main() !void {
    // Hash incremental
    var hasher = Sha256.init(.{});

    hasher.update("Parte 1: ");
    hasher.update("Olá, ");
    hasher.update("Zig ");
    hasher.update("Brasil!");

    var hash: [Sha256.digest_length]u8 = undefined;
    hasher.final(&hash);

    std.debug.print("Hash incremental: {s}\n", .{std.fmt.fmtSliceHexLower(&hash)});

    // Verificar que é igual ao hash direto
    var hash_direto: [Sha256.digest_length]u8 = undefined;
    Sha256.hash("Parte 1: Olá, Zig Brasil!", &hash_direto, .{});

    std.debug.print("Hash direto:      {s}\n", .{std.fmt.fmtSliceHexLower(&hash_direto)});
    std.debug.print("São iguais: {}\n", .{std.mem.eql(u8, &hash, &hash_direto)});
}
```

## Hash de Arquivo

```zig
const std = @import("std");
const Sha256 = std.crypto.hash.sha2.Sha256;

fn hashDeArquivo(caminho: []const u8) ![Sha256.digest_length]u8 {
    const arquivo = try std.fs.cwd().openFile(caminho, .{});
    defer arquivo.close();

    var hasher = Sha256.init(.{});
    var buf: [4096]u8 = undefined;

    while (true) {
        const n = try arquivo.read(&buf);
        if (n == 0) break;
        hasher.update(buf[0..n]);
    }

    var hash: [Sha256.digest_length]u8 = undefined;
    hasher.final(&hash);
    return hash;
}

pub fn main() !void {
    // Criar arquivo de teste
    const cwd = std.fs.cwd();
    {
        const f = try cwd.createFile("teste_hash.txt", .{});
        defer f.close();
        try f.writeAll("Conteúdo do arquivo para teste de hash.\n");
    }
    defer cwd.deleteFile("teste_hash.txt") catch {};

    const hash = try hashDeArquivo("teste_hash.txt");
    std.debug.print("SHA-256 de teste_hash.txt:\n{s}\n", .{std.fmt.fmtSliceHexLower(&hash)});
}
```

## Verificar Integridade

```zig
const std = @import("std");
const Sha256 = std.crypto.hash.sha2.Sha256;

fn verificarIntegridade(dados: []const u8, hash_esperado: []const u8) bool {
    var hash: [Sha256.digest_length]u8 = undefined;
    Sha256.hash(dados, &hash, .{});

    var hash_hex: [Sha256.digest_length * 2]u8 = undefined;
    _ = std.fmt.bufPrint(&hash_hex, "{s}", .{std.fmt.fmtSliceHexLower(&hash)}) catch return false;

    return std.mem.eql(u8, &hash_hex, hash_esperado);
}

pub fn main() !void {
    const dados = "dados importantes";

    // Calcular hash
    var hash: [Sha256.digest_length]u8 = undefined;
    Sha256.hash(dados, &hash, .{});
    var hash_hex: [64]u8 = undefined;
    _ = try std.fmt.bufPrint(&hash_hex, "{s}", .{std.fmt.fmtSliceHexLower(&hash)});

    std.debug.print("Hash original: {s}\n", .{hash_hex});

    // Verificar dados originais
    std.debug.print("Verificação (original): {}\n", .{
        verificarIntegridade(dados, &hash_hex),
    });

    // Verificar dados alterados
    std.debug.print("Verificação (alterado): {}\n", .{
        verificarIntegridade("dados modificados", &hash_hex),
    });
}
```

## Dicas e Boas Práticas

1. **Não use MD5 para segurança**: MD5 tem colisões conhecidas. Use SHA-256 ou SHA-512 para fins criptográficos.

2. **Hash incremental para dados grandes**: Use `init/update/final` para arquivos grandes sem carregar tudo na memória.

3. **`fmtSliceHexLower`**: A forma mais simples de converter hash em string hexadecimal.

4. **Hash de senhas**: Para senhas, use bcrypt ou Argon2 (não SHA ou MD5 diretamente).

## Receitas Relacionadas

- [Base64 Encoding/Decoding](/receitas/zig-base64-encode-decode/) - Codificação Base64
- [Hex Encoding/Decoding](/receitas/zig-hex-encode-decode/) - Hex para exibir hashes
- [Ler Conteúdo de Arquivo](/receitas/zig-ler-arquivo/) - Hash de arquivos
- [Compressão com Zlib](/receitas/zig-comprimir-zlib/) - Compressão de dados

## Tutoriais Relacionados

- [Introdução ao Zig](/tutoriais/introducao-ao-zig/)
