[#BF7] Got test fail when cast String to get piece hashes

I’m stuck on Stage #BF7

I’ve first tried to do String cast but I found out that it got wrong

Here are my logs:

remote: [tester::#BF7] Running ./your_program.sh info /tmp/torrents3080061021/test.torrent
remote: [your_program] Tracker URL: http://bttracker.debian.org:6969/announce
remote: [your_program] Length: 786432
remote: [your_program] Info Hash: 4fdbe0051276faacdeeadc97846c29b420afca34
remote: [your_program] Piece Length: 262144
remote: [your_program] Piece Hashes:
remote: [your_program] 3f301d263f52063f3f2d3f3f1e643f3f3f3f013f
remote: [your_program] 155a133f7c3c3f651d4f3f3f3f3f3f3f3f6b703f
remote: [your_program] 3f3f611a3f293f3f673f3f3f5d3f083f3f3f
remote: [tester::#BF7] Expected stdout to contain "8f301d26c6895206ec91de2df5971e64b4d2e1d5", g

And here’s a snippet of my code:

info = (Map<String, Object>) root.get("info");

        announce = (String) root.get("announce");
        length = (Long) info.get("length");
        try{
            MessageDigest messageDigest = MessageDigest.getInstance("SHA-1");
            byte[] encoded = messageDigest.digest(bencode2.encode(
                    (Map<String,Object>) bencode2.decode(bytes,Type.DICTIONARY).get("info")));
            infoHash = getInfoHash(encoded);
        }catch(NoSuchAlgorithmException e) {
            System.out.println("No such algorithm");
            infoHash = null;
        }
        pieceLength = (Long)info.get("piece length");
        System.out.println(length);
        String pieceString = (String) info.get("pieces");
        pieces = pieceString.getBytes();
        printPieceHashes(info);

System.out.print("Piece Hashes: ");
        byte[] piece = torrent.pieces;
        for(int i = 0; i < piece.length; ++i){
            if(i % 20 == 0){
                System.out.println();
            }
            System.out.printf("%02x",piece[i]);
        }

Thank you for helping me

i am also stuck, whenever I typecast to String, some characters are converted to ? which result in incorrect hash. what is the solution

You need to encode using true in BenCode constructor. this ensures, you encode using Bytes, so that you do not end up with ? in typecasting to String, you can then directly typecast to byte[] array. Here is the code snippet:


 public Torrent(byte[] bytes) throws NoSuchAlgorithmException {
        Bencode bencode1 = new Bencode(false);
        Bencode bencode2 = new Bencode(true);
        MessageDigest digest2 = MessageDigest.getInstance("SHA-1");

        Map<String, ?> root = bencode1.decode(bytes, Type.DICTIONARY);
        Map<String, ?> info = (Map<String, Object>) root.get("info");
        Map<String, ?> infoByteBuffer = (Map<String, ?>) bencode2.decode(bytes, Type.DICTIONARY).get("info");

        announce = (String) root.get("announce");
        length = (long) info.get("length");
        ByteBuffer pieceBuffer = (ByteBuffer) infoByteBuffer.get("pieces");
        pieces = new byte[pieceBuffer.remaining()];
        pieceBuffer.get(pieces);
        pieceLength = (long) info.get("piece length");
        infoHash = digest2.digest(bencode2.encode(infoByteBuffer));
    }

public List<byte[]> getPieces() {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i + 20 <= pieces.length; i += 20) {
            list.add(Arrays.copyOfRange(pieces, i, i + 20));
        }
        return list;
    }

Don’t forget to import the ByteBuffer line
import java.nio.ByteBuffer;

2 Likes

Thank you so much for helping me. I have tried your implementation and it worked

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.