enki b3204ea07a
Some checks are pending
CI Pipeline / Run Tests (push) Waiting to run
CI Pipeline / Lint Code (push) Waiting to run
CI Pipeline / Security Scan (push) Waiting to run
CI Pipeline / Build Docker Images (push) Blocked by required conditions
CI Pipeline / E2E Tests (push) Blocked by required conditions
first commit
2025-08-18 00:40:15 -07:00

92 lines
1.7 KiB
Go

package chunker
import (
"crypto/sha1"
"crypto/sha256"
"fmt"
"io"
)
const ChunkSize = 2 * 1024 * 1024 // 2MB
type Chunk struct {
Index int
Hash string // SHA-256 for Blossom
SHA1Hash [20]byte // SHA-1 for BitTorrent
Data []byte
Size int
}
type ChunkResult struct {
Chunks []Chunk
TotalSize int64
FileHash string
}
func ChunkFile(reader io.Reader) (*ChunkResult, error) {
var chunks []Chunk
var totalSize int64
index := 0
fileHasher := sha256.New()
for {
buffer := make([]byte, ChunkSize)
n, err := reader.Read(buffer)
if err != nil && err != io.EOF {
return nil, fmt.Errorf("error reading chunk: %w", err)
}
if n == 0 {
break
}
chunkData := buffer[:n]
// Update file hash
fileHasher.Write(chunkData)
// Calculate chunk hashes (both SHA-256 for Blossom and SHA-1 for BitTorrent)
sha256Hasher := sha256.New()
sha256Hasher.Write(chunkData)
chunkHash := fmt.Sprintf("%x", sha256Hasher.Sum(nil))
sha1Hasher := sha1.New()
sha1Hasher.Write(chunkData)
var sha1Hash [20]byte
copy(sha1Hash[:], sha1Hasher.Sum(nil))
chunks = append(chunks, Chunk{
Index: index,
Hash: chunkHash,
SHA1Hash: sha1Hash,
Data: chunkData,
Size: n,
})
totalSize += int64(n)
index++
if err == io.EOF {
break
}
}
fileHash := fmt.Sprintf("%x", fileHasher.Sum(nil))
return &ChunkResult{
Chunks: chunks,
TotalSize: totalSize,
FileHash: fileHash,
}, nil
}
func ReassembleChunks(chunks []Chunk, writer io.Writer) error {
for _, chunk := range chunks {
_, err := writer.Write(chunk.Data)
if err != nil {
return fmt.Errorf("error writing chunk %d: %w", chunk.Index, err)
}
}
return nil
}