2013-09-05 3 views
2

Я ищу, чтобы использовать какой-то уникальный идентификатор в файле .resx, но он не позволяет ключу начинать с номера. Вместо того, чтобы ездить на велосипеде по GUID до тех пор, пока я не получу тот, который начинается с письма, мне интересно, есть ли альтернативный тип UID, который либо не содержит цифр, либо в противном случае соответствует этому требованию.Как создать уникальный идентификатор, который не содержит чисел?

Любые мысли?

ответ

8

Если вы просто хотите создать Guid, что начинает с письмом, вы могли бы сделать что-то вроде этого:

var b = Guid.NewGuid().ToByteArray(); 
b[3] |= 0xF0; 
return new Guid(b); 

Это всегда будет генерировать GUID, который начинается с шестигранной цифры F.

Чтобы создать Guid, который не содержит любые номера вы можете использовать что-то вроде этого:

return new Guid(Guid.NewGuid().ToByteArray() 
    .Select(b => (byte)(((b % 16) < 10 ? 0xA : b) | 
         (((b >> 4) < 10 ? 0xA : (b >> 4)) << 4))) 
    .ToArray()); 

Это будет проверять каждую шестнадцатеричную цифру (два на один байт) и заставить его A, если он меньше чем A.


Оба эти решения порождают реальные объекты Guid, хотя добавленные ограничения делают уменьшить уникальность полученных GUIDs до некоторой степени (в гораздо большей степени во втором примере). Если вы не заботитесь о том, что вывод является фактическим GUID, вы можете просто переустановить шестнадцатеричные цифры на что-то еще и вернуть результат строке, как предложили другие. FWIW, вот кратчайшее решение я могу думать:

return String.Concat(Guid.NewGuid().ToString("N").Select(c => (char)(c + 17))); 

Это отображает шестнадцатеричные цифры от 0 до 9 для персонажей A через J, а шестнадцатеричные цифры A - F к персонажам r через w. Он также генерирует строку без дефиса. Это Например:

Before: e58d0f329a2f4615b922ecf53dcd090a 
After: vFIuAwDCJrCwEGBFsJCCvtwFDutuAJAr 

Конечно, вы могли бы преобразовать это в верхний или нижний случае, если вам не нравится смешанный случай здесь.

+2

Уверены ли, что это будет гарантировано уникальным? –

+1

@ HamletHakobyan: Даже GUID, полученные от 'Guid.NewGuid', без каких-либо искажений, не гарантируются как уникальные. Есть очень, очень, очень высокая вероятность. – cHao

+0

@HamletHakobyan Это, безусловно, не так уникально, как обычный Guid, потому что вы ограничиваете GUID только меньшим подмножеством гидов. Даже GUID не гарантированы *, чтобы быть уникальными, только настолько уникальными, что вы не будете разумно ожидать найти дубликат в течение всего времени жизни Вселенной. Как уникально вам нужно, чтобы они зависели от приложения. –

1

Просто напишите свой собственный GUID-генератор, допустимым символом будет a-z (вы также можете использовать A-Z для увеличения числа вероятностей).

1

Как насчет генерации уникального номера, а затем префикса его буквой? Таким образом, вместо

1234 

Вы бы использовать

a1234 

Пока алгоритм вы выбираете для идентификатора гарантирует уникальный номер, это должно работать нормально. Это также даст вам возможность отключить префикс и работать с идентификатором в виде номера, если это необходимо.

1

Создайте новый GUID и просто замените символы 0-9 символами g-p.

2

Предполагая, что вам это не нужно, чтобы быть действительным Guid (вы ссылаетесь на «какой-то уникальный идентификатор»), просто создайте строковый ориентир (используя Guid.NewGuid().ToString()), затем сопоставьте первую цифру с рядом подходящих буквы, например0 = G, 1 = H, 2 = I и т. Д.

1

Вы можете написать и использовать генератор псевдослучайных последовательностей. Вот тот, который дает основную идею:

class RandomLetterSequence { 
    private static Random r; 
    private static char MinChar = (char) 0x0061; 
    private static char MaxChar = (char) 0x007A; 

    public static string RandomSequence() { 
     return RandomSequence(32); 
    } 

    public static string RandomSequence(int length) { 
     if (r == null) 
      r = new Random(); 
     var sb = new StringBuilder(); 
     for (int i = length; i >= 0; i--) { 
      sb.Append((char)(r.Next(MinChar, MaxChar))); 
     } 
     return sb.ToString(); 
    } 
} 

С этой реализации, есть 26^32 возможных различных последовательностей, которые генерируются, которые соответствуют вашим требованиям:

  • Подобно GUIDs с точки зрения скорости столкновения (бесконечно мало)
  • Содержит только буквы