2012-04-28 1 views
2

У меня есть серия зашифрованных строк, которые я использую как идентификаторы в веб-приложении C#/ASP.Net. Мне нужно использовать их в атрибуте id, однако строка содержит недопустимые символы (допустимые символы - «[A-Za-z0-9 -_ :.]»). Мне нужен двухсторонний конвертер, который отображает мои зашифрованные строки на этот небольшой набор. Что-то вроде Base64, но меньше.Base64-подобный преобразование строк, для меньшего набора символов

Каковы мои альтернативы? Существуют ли для этого стандартные алгоритмы, или это достаточно странно, я должен сам это придумать?

В случае, если кому-то это нужно, вот что я в итоге сделал. Замените недействительные символы и удалите padding = char. Затем отмените это, чтобы вернуться.

private static string MakeReferenceJavascriptCompatible(string reference) 
    { 
     return reference.Replace("+", "_") 
         .Replace("/", "-") 
         .Replace("=", ""); 
    } 
    private static string UndoMakeReferenceJavascriptCompatible(string reference) 
    { 
     int padding = 4 - (reference.Length % 4); 
     return reference.Replace("-", "/") 
         .Replace("_", "+") 
         .PadRight(reference.Length + padding, '='); 
    } 

ответ

4

Если у вас есть A-Z (26), A-Z (26), 0-9 (10) и '_', ':' и '' (3), то у вас есть 65 символов, как и Base64. (Это нужно 65, а не 64 из-за использования = в качестве дополнения в конце.) Мне было не ясно, были ли вы также, включая -, что даст вам 66 ... положительно rich в доступных персонажах:)

Похоже, вам просто нужно преобразовать «нормальную» форму в ваш слегка отличающийся алфавит. Вы можете сделать это либо найти гибкую реализацию base64, который позволяет задать значения для использования, или просто позвонив string.Replace:

var base64 = Convert.ToBase64String(input) 
        .Replace('+', '_') 
        .Replace('/', ':') 
        .Replace('=', '.'); 

Поменяйте замены, чтобы получить от вашего «модифицированного» base64 к «нормальным» base64 и он будет действителен для Convert.FromBase64String.

+0

Я удивлен не понял, что я должен считать доступные символы ... Но, к сожалению, оказывается, что jQuery не нравится: и. в Идах, поэтому их все равно недостаточно. Хорошая идея! – carlpett

+0

Около 1 часа ночи я все равно делал это с помощью «-», «_» и «---» в качестве замещающих строк. Наверное, в один прекрасный день я кусаю меня, хотя ... – carlpett

+0

Это не здорово, нет. Возможно, вам удастся удалить отступы и просто вернуть его позже в зависимости от длины строки. Таким образом вам нужно всего 64 символа вместо 65. Помогает ли это? –

2

"Меньше"? В вопросе вы о том, что есть 66 действительных символов:

  • [AZ]: 26
  • [AZ]: 26
  • [0-9]: 10
  • [-_: .]: 4

Дайте Base64 шанс, возможно заменив «незаконные символы» (+, /, =) другими символами.

1

У вас уже есть 65 действительных символов для использования. Таким образом, вы можете использовать кодировку base64 с String.Replace. Но если вы хотите использовать кодировку без учета регистра (например, для использования для имени файла в окнах), вы можете использовать кодировку base36

+0

Как я заметил, что проблема с base64 в комментарии к Jon Skeet, Base36 - интересная альтернатива. Спасибо за ссылку, я проверю это! – carlpett

+0

@carlpett Если вас интересует кодировка Base64, существует множество других его реализаций, таких как [этот] (http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/ core/Support/Number.cs? view = co), используемый в Lucene.Net. –

0

Для этого вы можете использовать встроенную System.Web.HttpServerUtility.

Для преобразования значения в закодированном значение (безопасное для Url и JavaScript использования):

string result = value; 
if (!string.IsNullOrEmpty(value)) 
{ 
    var bytes = System.Text.Encoding.UTF8.GetBytes(value); 
    result = HttpServerUtility.UrlTokenEncode(bytes); 
} 
return result; 

Чтобы преобразовать закодированное значение обратно к исходному значению:

// If a non-base64 string is passed as value, the result will 
// be same as the passed value 
string result = value; 
if (!string.IsNullOrEmpty(value)) 
{ 
    var bytes = HttpServerUtility.UrlTokenDecode(value); 
    if (bytes != null) { 
    result = System.Text.Encoding.UTF8.GetString(bytes); 
    } 
} 
return result; 
Смежные вопросы