Skip to content

Commit

Permalink
feat(torrenfile): parsing & encoding torrent file
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianLusina committed Jul 15, 2022
1 parent 759098e commit fb80785
Show file tree
Hide file tree
Showing 6 changed files with 28,345 additions and 0 deletions.
71 changes: 71 additions & 0 deletions pkg/torrentfile/bencode.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package torrentfile

import (
"bytes"
"crypto/sha1"
"fmt"

"github.com/jackpal/bencode-go"
)

type bencodeInfo struct {
Pieces string `bencode:"pieces"`
PiecesLength int `bencode:"piece length"`
Length int `bencode:"length"`
Name string `bencode:"name"`
}

type bencodeTorrent struct {
Announce string `bencode:"announce"`
Info bencodeInfo `bencode:"info"`
}

func (bto *bencodeTorrent) toTorrentFile() (TorrentFile, error) {
infoHash, err := bto.Info.hash()
if err != nil {
return TorrentFile{}, err
}

piecesHash, err := bto.Info.splitPieacesHash()
if err != nil {
return TorrentFile{}, err
}

t := TorrentFile{
Announce: bto.Announce,
InfoHash: infoHash,
PieceHashes: piecesHash,
PieceLength: bto.Info.PiecesLength,
Length: bto.Info.Length,
Name: bto.Info.Name,
}

return t, nil
}

func (bi *bencodeInfo) hash() ([20]byte, error) {
var buf bytes.Buffer
err := bencode.Marshal(&buf, *bi)
if err != nil {
return [20]byte{}, err
}
h := sha1.Sum(buf.Bytes())
return h, nil
}

func (bi *bencodeInfo) splitPieacesHash() ([][20]byte, error) {
// length of SHA-1 hash
hashLen := 20
buf := []byte(bi.Pieces)
if len(buf)%hashLen != 0 {
err := fmt.Errorf("Received malformed pieces of length %d", len(buf))
return nil, err
}
numHashes := len(buf) / hashLen
hashes := make([][20]byte, numHashes)

for i := 0; i < numHashes; i++ {
copy(hashes[i][:], buf[i*hashLen:(i+1)*hashLen])
}
return hashes, nil
}
Binary file not shown.

0 comments on commit fb80785

Please sign in to comment.