руководство к base64, для URL
Вопрос
Вопрос:есть ли лучший способ сделать это?
ВБ.Нет
Function GuidToBase64(ByVal guid As Guid) As String
Return Convert.ToBase64String(guid.ToByteArray).Replace("/", "-").Replace("+", "_").Replace("=", "")
End Function
Function Base64ToGuid(ByVal base64 As String) As Guid
Dim guid As Guid
base64 = base64.Replace("-", "/").Replace("_", "+") & "=="
Try
guid = New Guid(Convert.FromBase64String(base64))
Catch ex As Exception
Throw New Exception("Bad Base64 conversion to GUID", ex)
End Try
Return guid
End Function
С#
public string GuidToBase64(Guid guid)
{
return Convert.ToBase64String(guid.ToByteArray()).Replace("/", "-").Replace("+", "_").Replace("=", "");
}
public Guid Base64ToGuid(string base64)
{
Guid guid = default(Guid);
base64 = base64.Replace("-", "/").Replace("_", "+") + "==";
try {
guid = new Guid(Convert.FromBase64String(base64));
}
catch (Exception ex) {
throw new Exception("Bad Base64 conversion to GUID", ex);
}
return guid;
}
Решение
Я понимаю, что причина, по которой вы в конце концов обрезаете ==, заключается в том, что, поскольку вы можете быть уверены, что для GUID (16 байтов) закодированная строка будет всегда заканчиваться на ==.Таким образом, при каждом преобразовании можно сохранить 2 символа.
Помимо уже упомянутого момента @Skurmedal (должно выдать исключение в случае ввода недопустимой строки), я думаю, что опубликованный вами код достаточно хорош.
Другие советы
Возможно, вам захочется заглянуть на этот сайт: http://prettycode.org/2009/11/12/short-guid/
Это очень похоже на то, что вы делаете.
public class ShortGuid
{
private readonly Guid guid;
private readonly string value;
/// <summary>Create a 22-character case-sensitive short GUID.</summary>
public ShortGuid(Guid guid)
{
if (guid == null)
{
throw new ArgumentNullException("guid");
}
this.guid = guid;
this.value = Convert.ToBase64String(guid.ToByteArray())
.Substring(0, 22)
.Replace("/", "_")
.Replace("+", "-");
}
/// <summary>Get the short GUID as a string.</summary>
public override string ToString()
{
return this.value;
}
/// <summary>Get the Guid object from which the short GUID was created.</summary>
public Guid ToGuid()
{
return this.guid;
}
/// <summary>Get a short GUID as a Guid object.</summary>
/// <exception cref="System.ArgumentNullException"></exception>
/// <exception cref="System.FormatException"></exception>
public static ShortGuid Parse(string shortGuid)
{
if (shortGuid == null)
{
throw new ArgumentNullException("shortGuid");
}
else if (shortGuid.Length != 22)
{
throw new FormatException("Input string was not in a correct format.");
}
return new ShortGuid(new Guid(Convert.FromBase64String
(shortGuid.Replace("_", "/").Replace("-", "+") + "==")));
}
public static implicit operator String(ShortGuid guid)
{
return guid.ToString();
}
public static implicit operator Guid(ShortGuid shortGuid)
{
return shortGuid.guid;
}
}
Одна из проблем с использованием этого метода для форматирования GUID для использования в URL-адресе или имени файла заключается в том, что два разных GUID могут создавать два значения, которые различаются только регистром, например:
var b1 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab83c"));
var b2 = GuidToBase64(new Guid("c9d045f3-e21c-46d0-971d-b92ebc2ab8a4"));
Console.WriteLine(b1); // 80XQyRzi0EaXHbkuvCq4PA
Console.WriteLine(b2); // 80XQyRzi0EaXHbkuvCq4pA
Поскольку URL-адреса иногда интерпретируются как нечувствительные к регистру, а в Windows пути к файлам и имена файлов не учитывают регистр.это может привести к столкновениям.
Если ваш метод не может преобразовать переданный ему Base64 в GUID, не следует ли вам создать исключение?Данные, передаваемые в метод, явно ошибочны.