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 }