From 8fa78dd067d274c165f16d50dc18593fcd7f25e4 Mon Sep 17 00:00:00 2001 From: SimonLab Date: Tue, 22 Jan 2019 16:22:28 +0000 Subject: [PATCH] decode cid v0, #13 #15 --- lib/cid.ex | 39 +++++++++++++++++++++++++++++++++++++++ test/cid_test.exs | 8 ++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/cid.ex b/lib/cid.ex index 2ac2bb3..f96c6fe 100644 --- a/lib/cid.ex +++ b/lib/cid.ex @@ -35,4 +35,43 @@ defmodule Cid do |> Enum.map(fn (x) -> Map.get(input_map, x) end) |> Enum.join("") end + + # check for cid v0. It needs to be a binary ie a string with length 46 + def decode(cid) when is_binary(cid) do + if String.length(cid) == 46 do # why 46? we could also use byte_size as + case cid do + <<"Qm", _rest :: binary >> -> {:ok, "cidv0"} + _ -> multibase_decode(cid) + end + + else + multibase_decode(cid) + end + end + + def multibase_decode(cid) do + # TODO cid follow v1 format, find base then get binary + {:ok, "cidv1"} + end + + #1 - If it's a string (ASCII/UTF-8): + # + # If it is 46 characters long and starts with Qm..., it's a CIDv0. Decode it as base58btc and continue to step 2. + # Otherwise, decode it according to the multibase spec and: + # If the first decoded byte is 0x12, return an error. CIDv0 CIDs may not be multibase encoded and there will be no CIDv18 (0x12 = 18) to prevent ambiguity with decoded CIDv0s. + # Otherwise, you now have a binary CID. Continue to step 2. + # + #2 - Given a (binary) CID (cid): + # If it's 34 bytes long with the leading bytes [0x12, 0x20, ...], it's a CIDv0. + # The CID's multihash is cid. + # The CID's multicodec is DagProtobuf + # The CID's version is 0. + # Otherwise, let N be the first varint in cid. This is the CID's version. + # If N == 1 (CIDv1): + # The CID's multicodec is the second varint in cid + # The CID's multihash is the rest of the cid (after the second varint). + # The CID's version is 1. + # If N <= 0, the CID is malformed. + # If N > 1, the CID version is reserved. + end diff --git a/test/cid_test.exs b/test/cid_test.exs index ab6c192..3a7a43a 100644 --- a/test/cid_test.exs +++ b/test/cid_test.exs @@ -15,4 +15,12 @@ defmodule CidTest do assert Cid.make("hello world") == "MJ7MSJwS1utMxA9QyQLytNDtd5RGnx6m" end + test "Cid.decode cidv0 format" do + assert Cid.decode("QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB") == {:ok, "cidv0"} + end + + test "Cid.decode cidv1 format" do + assert Cid.decode("wrongcid") == {:ok, "cidv1"} + end + end