diff options
| author | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 18:14:24 +0000 |
|---|---|---|
| committer | jet2tlf <jet2tlf@gmail.com> | 2024-06-03 18:14:24 +0000 |
| commit | 853be358804a6e30e857035ffda81a06df3f6b74 (patch) | |
| tree | eae9b736261ef6887c4070c7bf1e5a441ccb5319 /cmd/mybittorrent/meta.go | |
| parent | adf38a1dbd085c19c4c87ad242e0b340f1655fcb (diff) | |
| download | bittorrent-go-853be358804a6e30e857035ffda81a06df3f6b74.tar.gz bittorrent-go-853be358804a6e30e857035ffda81a06df3f6b74.zip | |
codecrafters submit [skip ci]
Diffstat (limited to 'cmd/mybittorrent/meta.go')
| -rw-r--r-- | cmd/mybittorrent/meta.go | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/cmd/mybittorrent/meta.go b/cmd/mybittorrent/meta.go index 34369c4..27bcc12 100644 --- a/cmd/mybittorrent/meta.go +++ b/cmd/mybittorrent/meta.go @@ -1,11 +1,15 @@ package main import ( + "bytes" "crypto/sha1" + "math" bencode "github.com/jackpal/bencode-go" ) +const BlockSize = 16 * 1024 + type Meta struct { Announce string `bencode:"announce"` Info FileInfo `bencode:"info"` @@ -35,3 +39,48 @@ func (m Meta) PieceHashes() []string { return hashes } + +func (m Meta) CheckHash(pieceIndex int, data []byte) bool { + sha := sha1.New() + + if _, err := bytes.NewBuffer(data).WriteTo(sha); err != nil { + return false + } + + return bytes.Equal([]byte(m.Info.Pieces[pieceIndex*20:pieceIndex*20+20]), sha.Sum(nil)) +} + +func (m Meta) PieceCount() int { + return len(m.Info.Pieces) / 20 +} + +func (m Meta) PieceLens() []int { + pieceCnt := m.PieceCount() + pieces := make([]int, pieceCnt) + + for i := 0; i < pieceCnt; i++ { + if i < pieceCnt-1 { + pieces[i] = m.Info.PieceLength + } else { + pieces[i] = m.Info.Length - i*m.Info.PieceLength + } + } + + return pieces +} + +func (m Meta) BlockLens(pieceIdx int) []uint32 { + pieceLen := m.PieceLens()[pieceIdx] + blockCnt := int(math.Ceil(float64(pieceLen) / float64(BlockSize))) + blocks := make([]uint32, blockCnt) + + for i := 0; i < blockCnt; i++ { + if i < blockCnt-1 { + blocks[i] = uint32(BlockSize) + } else { + blocks[i] = uint32(pieceLen - i*BlockSize) + } + } + + return blocks +} |