Combined Guids media path scheme
This commit is contained in:
@@ -40,5 +40,72 @@ namespace Umbraco.Core
|
||||
|
||||
public DecomposedGuid(Guid value) : this() => this.Value = value;
|
||||
}
|
||||
|
||||
private static readonly char[] Base32Table =
|
||||
{
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
|
||||
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5'
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Converts a Guid into a base-32 string.
|
||||
/// </summary>
|
||||
/// <param name="guid">A Guid.</param>
|
||||
/// <param name="length">The string length.</param>
|
||||
/// <returns>A base-32 encoded string.</returns>
|
||||
/// <remarks>
|
||||
/// <para>A base-32 string representation of a Guid is the shortest, efficient, representation
|
||||
/// that is case insensitive (base-64 is case sensitive).</para>
|
||||
/// <para>Length must be 1-26, anything else becomes 26.</para>
|
||||
/// </remarks>
|
||||
public static string ToBase32String(Guid guid, int length = 26)
|
||||
{
|
||||
if (length <= 0 || length > 26)
|
||||
length = 26;
|
||||
|
||||
var bytes = guid.ToByteArray(); // a Guid is 128 bits ie 16 bytes
|
||||
|
||||
// this could be optimized by making it unsafe,
|
||||
// and fixing the table + bytes + chars (see Convert.ToBase64CharArray)
|
||||
|
||||
// each block of 5 bytes = 5*8 = 40 bits
|
||||
// becomes 40 bits = 8*5 = 8 byte-32 chars
|
||||
// a Guid is 3 blocks + 8 bits
|
||||
|
||||
// so it turns into a 3*8+2 = 26 chars string
|
||||
var chars = new char[length];
|
||||
|
||||
var i = 0;
|
||||
var j = 0;
|
||||
|
||||
while (i < 15)
|
||||
{
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i] & 0b1111_1000) >> 3];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i] & 0b0000_0111) << 2) | ((bytes[i + 1] & 0b1100_0000) >> 6)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 1] & 0b0011_1110) >> 1];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 1] & 0b0000_0001) | ((bytes[i + 2] & 0b1111_0000) >> 4)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i + 2] & 0b0000_1111) << 1) | ((bytes[i + 3] & 0b1000_0000) >> 7)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[(bytes[i + 3] & 0b0111_1100) >> 2];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[((bytes[i + 3] & 0b0000_0011) << 3) | ((bytes[i + 4] & 0b1110_0000) >> 5)];
|
||||
if (j == length) break;
|
||||
chars[j++] = Base32Table[bytes[i + 4] & 0b0001_1111];
|
||||
|
||||
i += 5;
|
||||
}
|
||||
|
||||
if (j < length)
|
||||
chars[j++] = Base32Table[(bytes[i] & 0b1111_1000) >> 3];
|
||||
if (j < length)
|
||||
chars[j] = Base32Table[(bytes[i] & 0b0000_0111) << 2];
|
||||
|
||||
return new string(chars);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user