/*** * Turn a multibase decoded string of bytes into a Cid struct * @param incoming the multibase decoded array * @param incoming_size the size of the array * @param cid the Cid structure to fill */ int ipfs_cid_cast(const unsigned char* incoming, size_t incoming_size, struct Cid* cid) { if (incoming_size == 34 && incoming[0] == 18 && incoming[1] == 32) { // this is a multihash cid->hash_length = mh_multihash_length(incoming, incoming_size); cid->codec = CID_PROTOBUF; cid->version = 0; mh_multihash_digest(incoming, incoming_size, &cid->hash, &cid->hash_length); return 1; } // This is not a multihash. Perhaps it is using varints. Try to peel the information out of the bytes. // first the version int pos = 0; size_t num_bytes = 0; cid->version = varint_decode(&incoming[pos], incoming_size - pos, &num_bytes); if (num_bytes == 0 || cid->version > 1 || cid->version < 0) return 0; pos = num_bytes; // now the codec uint32_t codec = 0; codec = varint_decode(&incoming[pos], incoming_size - pos, &num_bytes); if (num_bytes == 0) return 0; cid->codec = codec; pos += num_bytes; // now what is left cid->hash_length = incoming_size - pos; cid->hash = (unsigned char*)(&incoming[pos]); return 1; }
/** * gives access to raw digest inside multihash buffer * @param multihash the multihash * @param len the length * @param digest the results * @returns error if less than zero, otherwise 0 */ int mh_multihash_digest(const unsigned char *multihash, size_t len, unsigned char **digest, size_t *digest_len) { int err = check_multihash(multihash, len); if (err) return err; (*digest_len) = (size_t) mh_multihash_length(multihash, len); (*digest) = (unsigned char*)multihash + 2; // Always true without varint return 0; }
static char *test_multihash_new_is_reversible(void) { int error = MH_E_NO_ERROR; int code = MH_H_SHA3_512; const unsigned char *digest = random_512; const size_t digest_len = 512 / 8; unsigned char mh[256]; const size_t mh_len = mh_new_length(code, digest_len); error = mh_new(mh, MH_H_SHA3_512, digest, digest_len); mu_assert("creating multihash", error == MH_E_NO_ERROR); mu_assert("reading code", mh_multihash_hash(mh, mh_len) == MH_H_SHA3_512); mu_assert("reading length", mh_multihash_length(mh, mh_len) == (int) digest_len); return NULL; }