CID.fromString constructor
CID.fromString(
- String s
Decodes a CID from its string representation.
Supports:
- CIDv0: Base58btc encoded multihashes (e.g., "Qm...").
- CIDv1: Multibase-prefixed strings. Currently, it specifically handles:
- Base32 (prefix 'b', e.g., "bafy...") - canonical form.
- Base58btc (prefix 'z', e.g., "zdj7...") - common alternative.
Throws FormatException if the string is empty, has an unsupported multibase prefix, or is otherwise malformed.
s
: The CID string to parse.
Example:
final cidV0 = CID.fromString('QmWvQxTqbG2Z9HPJgG57jjwR154cKhbtJenbyYTWkjgF3e');
final cidV1 = CID.fromString('bafybeid7qoywk77r7rj3slobqfekdvs57qwuwh5d2z3sqsw52iabe3mqne');
Implementation
factory CID.fromString(String s) {
if (s.isEmpty) {
throw FormatException('Cannot parse CID from empty string');
}
// CIDv0: Starts with "Qm", is Base58btc encoded multihash.
// Length of a sha2-256 multihash (32-byte hash + 2-byte prefix) is 34 bytes.
// Base58 encoded, it's typically 46 characters long (e.g. Qm...).
if (s.length == 46 && s.startsWith('Qm')) {
try {
final multihashBytes = mb.base58.decode(s);
// Validate it's a sha2-256 multihash
final decodedMh = mh.Multihash.decode(multihashBytes);
// Assuming 'digest' is the property holding the hash bytes, and its length is what we need.
if (decodedMh.code == codecNameToCode['sha2-256']! && decodedMh.digest.length == 32) {
return CID(V0, codecNameToCode['dag-pb']!, multihashBytes);
} else {
throw FormatException('CIDv0 string is not a valid sha2-256 multihash');
}
} catch (e) {
throw FormatException('Failed to parse CIDv0 string "$s": $e');
}
}
// CIDv1: Starts with a multibase prefix. For canonical form, this is 'b' (base32).
if (s.length > 1) {
final prefix = s[0];
final rest = s.substring(1);
// For now, we only support base32 ('b') for CIDv1 string parsing
// and base58btc ('z') as a common alternative for CIDv1.
// A full multibase implementation would be more robust.
if (prefix == 'b') { // base32
try {
// The base32 package might require uppercase and padding for decoding.
// The input 'rest' should be base32 encoded data.
// Standard Base32 alphabet: ABCDEFGHIJKLMNOPQRSTUVWXYZ234567
// We need to handle potential lowercase input by converting to uppercase.
// Padding might also need to be re-added if the decoder expects it.
String toDecode = rest.toUpperCase();
// Add padding if necessary for the decoder
final missingPadding = (8 - (toDecode.length % 8)) % 8;
toDecode += '=' * missingPadding;
final decodedBytes = b32.base32.decode(toDecode);
return CID.fromBytes(decodedBytes);
} catch (e) {
throw FormatException('Failed to parse CIDv1 base32 string "$s": $e');
}
} else if (prefix == 'z') { // base58btc (often used for CIDv1 too)
try {
final decodedBytes = mb.base58.decode(rest);
return CID.fromBytes(decodedBytes);
} catch (e) {
throw FormatException('Failed to parse CIDv1 base58btc string "$s": $e');
}
}
// Add other multibase prefixes if needed
}
throw FormatException('Invalid CID string format: "$s"');
}