/// <summary> /// Converts the specified <see cref="string"/> /// to an equivalent <see cref="Cid"/> object. /// </summary> /// <param name="input"> /// The <see cref="Cid.Encode">CID encoded</see> string. /// </param> /// <returns> /// A new <see cref="Cid"/> that is equivalent to <paramref name="input"/>. /// </returns> /// <exception cref="FormatException"> /// When the <paramref name="input"/> can not be decoded. /// </exception> /// <seealso cref="Encode"/> public static Cid Decode(string input) { try { // SHA2-256 MultiHash is CID v0. if (input.Length == 46 && input.StartsWith("Qm")) { return((Cid) new MultiHash(input)); } using (var ms = new MemoryStream(MultiBase.Decode(input), false)) { var version = ms.ReadVarint32(); if (version != 1) { throw new InvalidDataException($"Unknown CID version '{version}'."); } return(new Cid { Version = version, Encoding = Registry.MultiBaseAlgorithm.Codes[input[0]].Name, ContentType = ms.ReadMultiCodec().Name, Hash = new MultiHash(ms) }); } } catch (Exception e) { throw new FormatException($"Invalid CID '{input}'.", e); } }
/// <summary> /// Returns a string representation of the CID /// according to the provided format specifier. /// </summary> /// <param name="format"> /// A single format specifier that indicates how to format the value of the /// CID. Can be "G" or "L". /// </param> /// <returns> /// The CID in the specified <paramref name="format"/>. /// </returns> /// <exception cref="FormatException"> /// <paramref name="format"/> is not valid. /// </exception> /// <remarks> /// <para> /// The "G" format specifier is the same as calling <see cref="Encode"/>. /// </para> /// <list type="table"> /// <listheader> /// <term>Specifier</term> /// <description>return value</description> /// </listheader> /// <item> /// <term>G</term> /// <description>QmXg9Pp2ytZ14xgmQjYEiHjVjMFXzCVVEcRTWJBmLgR39V</description> /// </item> /// <item> /// <term>L</term> /// <description>base58btc cidv0 dag-pb sha2-256 Qm...</description> /// </item> /// </list> /// </remarks> public string ToString(string format) { switch (format) { case "G": return(Encode()); case "L": var sb = new StringBuilder(); sb.Append(Encoding); sb.Append(' '); sb.Append("cidv"); sb.Append(Version); sb.Append(' '); sb.Append(ContentType); if (Hash != null) { sb.Append(' '); sb.Append(Hash.Algorithm.Name); sb.Append(' '); sb.Append(MultiBase.Encode(Hash.ToArray(), Encoding).Substring(1)); } return(sb.ToString()); default: throw new FormatException($"Invalid CID format specifier '{format}'."); } }
public void Invalid_Encoded_String() { foreach (var alg in MultiBaseAlgorithm.All) { var bad = alg.Code + "?"; ExceptionAssert.Throws <FormatException>(() => MultiBase.Decode(bad)); } }
public void Codec() { var bytes = new byte[] { 1, 2, 3, 4, 5 }; var bytes1 = MultiBase.Decode(MultiBase.Encode(bytes)); var bytes2 = MultiBase.Decode(MultiBase.Encode(bytes, "base16")); CollectionAssert.AreEqual(bytes, bytes1); CollectionAssert.AreEqual(bytes, bytes2); }
public void EmptyData() { var empty = new byte[0]; foreach (var alg in MultiBaseAlgorithm.All) { var s = MultiBase.Encode(empty, alg.Name); CollectionAssert.AreEqual(empty, MultiBase.Decode(s), alg.Name); } }
public void CheckMultiBase() { foreach (var v in TestVectors) { var bytes = Encoding.UTF8.GetBytes(v.Input); var s = MultiBase.Encode(bytes, v.Algorithm); Assert.AreEqual(v.Output, s); CollectionAssert.AreEqual(bytes, MultiBase.Decode(s)); } }
public void Decode_Bad_Formats() { ExceptionAssert.Throws <ArgumentNullException>(() => MultiBase.Decode(null)); ExceptionAssert.Throws <ArgumentNullException>(() => MultiBase.Decode("")); ExceptionAssert.Throws <ArgumentNullException>(() => MultiBase.Decode(" ")); ExceptionAssert.Throws <FormatException>(() => MultiBase.Decode("?")); ExceptionAssert.Throws <FormatException>(() => MultiBase.Decode("??")); ExceptionAssert.Throws <FormatException>(() => MultiBase.Decode("???")); ExceptionAssert.Throws <FormatException>(() => MultiBase.Decode("fXX")); }
/// <summary> /// Converts the CID to its equivalent string representation. /// </summary> /// <returns> /// The string representation of the <see cref="Cid"/>. /// </returns> /// <remarks> /// For <see cref="Version"/> 0, this is equalivalent to the /// <see cref="MultiHash.ToBase58()">base58btc encoding</see> /// of the <see cref="Hash"/>. /// </remarks> /// <seealso cref="Decode"/> public string Encode() { if (Version == 0) { return(Hash.ToBase58()); } using (var ms = new MemoryStream()) { ms.WriteVarint(Version); ms.WriteMultiCodec(ContentType); Hash.Write(ms); return(MultiBase.Encode(ms.ToArray(), Encoding)); } }
/// <summary> /// A CID that is readable by a human. /// </summary> /// <returns> /// e.g. "base58btc cidv0 dag-pb sha2-256 Qm..." /// </returns> public override string ToString() { var sb = new StringBuilder(); sb.Append(Encoding); sb.Append(' '); sb.Append("cidv"); sb.Append(Version); sb.Append(' '); sb.Append(ContentType); if (Hash != null) { sb.Append(' '); sb.Append(Hash.Algorithm.Name); sb.Append(' '); sb.Append(MultiBase.Encode(Hash.ToArray(), Encoding).Substring(1)); } return sb.ToString(); }
/// <summary> /// Converts the CID to its equivalent string representation. /// </summary> /// <returns> /// The string representation of the <see cref="Cid"/>. /// </returns> /// <remarks> /// For <see cref="Version"/> 0, this is equalivalent to the /// <see cref="MultiHash.ToBase58()">base58btc encoding</see> /// of the <see cref="Hash"/>. /// </remarks> /// <seealso cref="Decode"/> public string Encode() { if (encodedValue != null) return encodedValue; if (Version == 0) { encodedValue = Hash.ToBase58(); } else { using (var ms = new MemoryStream()) { ms.WriteVarint(Version); ms.WriteMultiCodec(ContentType); Hash.Write(ms); encodedValue = MultiBase.Encode(ms.ToArray(), Encoding); } } return encodedValue; }
public void Encode_Null_Data_Not_Allowed() { ExceptionAssert.Throws <ArgumentNullException>(() => MultiBase.Encode(null)); }
public void Encode_Unknown_Algorithm() { var bytes = new byte[] { 1, 2, 3, 4, 5 }; ExceptionAssert.Throws <KeyNotFoundException>(() => MultiBase.Encode(bytes, "unknown")); }