.NET 짧은 고유 식별자
.NET에서 고유 식별자가 필요합니다 (이 경우 GUID가 너무 길기 때문에 사용할 수 없음).
사람들은 여기 에 사용 된 알고리즘 이 좋은 후보 라고 생각 합니까, 아니면 다른 제안이 있습니까?
이것은 좋은 것입니다-http: //www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx
Base64를 사용할 수 있습니다.
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
그러면 E1HKfn68Pkms5zsZsvKONw ==와 같은 문자열이 생성됩니다. GUID는 항상 128 비트이므로 ==를 생략 할 수 있습니다. ==는 항상 끝에 존재하며 22 자 문자열을 제공합니다. 그래도 YouTube만큼 짧지는 않습니다.
Dor Cohen과 비슷한 접근 방식을 사용하지만 일부 특수 문자를 제거합니다.
var uid = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", "");
이것은 영숫자 문자 만 출력합니다. UID의 길이가 항상 동일하다고 보장 할 수는 없습니다. 다음은 샘플 실행입니다.
vmKo0zws8k28fR4V4Hgmw
TKbhS0G2V0KqtpHOU8e6Ug
rfDi1RdO0aQHTosh9dVvw
3jhCD75fUWjQek8XRmMg
CQUg1lXIXkWG8KDFy7z6Ow
bvyxW5aj10OmKA5KMhppw
pIMK8eq5kyvLK67xtsIDg
VX4oljGWpkSQGR2OvGoOQ
NOHBjUUHv06yIc7EvotRg
iMniAuUG9kiGLwBtBQByfg
var ticks = new DateTime(2016,1,1).Ticks;
var ans = DateTime.Now.Ticks - ticks;
var uniqueId = ans.ToString("x");
이러한 ID 생성을 시작할 기준 날짜 (이 경우 2016 년 1 월 1 일)를 유지합니다. 이렇게하면 ID가 작아집니다.
생성 된 수 : 3af3c14996e54
간단하게 사용할 수있는 패키지. 임시 요청 ID 생성기에 사용합니다.
https://www.nuget.org/packages/shortid
https://github.com/bolorundurowb/shortid
용도 System.Random
string id = ShortId.Generate();
// id = KXTR_VzGVUoOY
(github 페이지에서)
숫자, 특수 문자 및 길이를 원하는지 여부를 지정하여 생성 된 ID 유형을 제어하려면 Generate 메서드를 호출하고 세 개의 매개 변수를 전달합니다. 첫 번째는 숫자를 원하는지 여부를 나타내는 부울, 두 번째는 원하는 여부를 나타내는 부울입니다. 특수 문자, 마지막은 선호하는 길이를 나타내는 숫자입니다.
string id = ShortId.Generate(true, false, 12);
// id = VvoCDPazES_w
내가 아는 한, GUID의 일부를 제거하는 것이 고유하다고 보장 할 수는 없습니다 . 사실 고유 한 것과는 거리가 멀습니다.
글로벌 고유성을 보장하는 가장 짧은 것은 Jeff Atwood의이 블로그 게시물에 나와 있습니다. 링크 된 게시물에서 그는 GUID를 줄이는 여러 방법에 대해 논의하고 결국 Ascii85 인코딩을 통해 20 바이트로 줄 입니다.
그러나 15 바이트 이하의 솔루션이 절대적으로 필요한 경우 전역 적으로 고유하다고 보장되지 않는 것을 사용하는 것 외에 다른 선택의 여지가 없습니다.
IDENTITY 값은 데이터베이스에서 고유해야하지만 제한 사항을 알고 있어야합니다. 예를 들어 대량 데이터 삽입이 기본적으로 불가능 해져서 매우 많은 수의 레코드로 작업하는 경우 속도가 느려집니다.
날짜 / 시간 값을 사용할 수도 있습니다. 날짜 / 시간을 PK로 사용하는 데이터베이스를 여러 개 보았습니다. 매우 깨끗하지는 않지만 작동합니다. 삽입을 제어하면 값이 코드에서 고유하다는 것을 효과적으로 보장 할 수 있습니다.
내 로컬 앱의 경우이 시간 기반 접근 방식을 사용하고 있습니다.
/// <summary>
/// Returns all ticks, milliseconds or seconds since 1970.
///
/// 1 tick = 100 nanoseconds
///
/// Samples:
///
/// Return unit value decimal length value hex length
/// --------------------------------------------------------------------------
/// ticks 14094017407993061 17 3212786FA068F0 14
/// milliseconds 1409397614940 13 148271D0BC5 11
/// seconds 1409397492 10 5401D2AE 8
///
/// </summary>
public static string TickIdGet(bool getSecondsNotTicks, bool getMillisecondsNotTicks, bool getHexValue)
{
string id = string.Empty;
DateTime historicalDate = new DateTime(1970, 1, 1, 0, 0, 0);
if (getSecondsNotTicks || getMillisecondsNotTicks)
{
TimeSpan spanTillNow = DateTime.UtcNow.Subtract(historicalDate);
if (getSecondsNotTicks)
id = String.Format("{0:0}", spanTillNow.TotalSeconds);
else
id = String.Format("{0:0}", spanTillNow.TotalMilliseconds);
}
else
{
long ticksTillNow = DateTime.UtcNow.Ticks - historicalDate.Ticks;
id = ticksTillNow.ToString();
}
if (getHexValue)
id = long.Parse(id).ToString("X");
return id;
}
앱에 몇 백만 명의 사용자가없는 경우 동일한 MILLISECOND에서 짧은 고유 문자열을 생성하는 것을 사용하면 아래 함수를 사용할 수 있습니다.
private static readonly Object obj = new Object();
private static readonly Random random = new Random();
private string CreateShortUniqueString()
{
string strDate = DateTime.Now.ToString("yyyyMMddhhmmssfff");
string randomString ;
lock (obj)
{
randomString = RandomString(3);
}
return strDate + randomString; // 16 charater
}
private string RandomString(int length)
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxy";
var random = new Random();
return new string(Enumerable.Repeat(chars, length)
.Select(s => s[random.Next(s.Length)]).ToArray());
}
향후 99 년 동안 앱을 사용해야하는 경우 yyyy를 yy로 변경하십시오.
20160511 업데이트 : 임의 기능 수정
-잠금 개체 추가
-RandomString 함수 참조에서 임의 변수 이동
여기 내 솔루션은 동시성, 초당 1000 GUID 및 스레드 안전에 안전하지 않습니다.
public static class Extensors
{
private static object _lockGuidObject;
public static string GetGuid()
{
if (_lockGuidObject == null)
_lockGuidObject = new object();
lock (_lockGuidObject)
{
Thread.Sleep(1);
var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
var epochLong = Convert.ToInt64((DateTime.UtcNow - epoch).TotalMilliseconds);
return epochLong.DecimalToArbitrarySystem(36);
}
}
/// <summary>
/// Converts the given decimal number to the numeral system with the
/// specified radix (in the range [2, 36]).
/// </summary>
/// <param name="decimalNumber">The number to convert.</param>
/// <param name="radix">The radix of the destination numeral system (in the range [2, 36]).</param>
/// <returns></returns>
public static string DecimalToArbitrarySystem(this long decimalNumber, int radix)
{
const int BitsInLong = 64;
const string Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (radix < 2 || radix > Digits.Length)
throw new ArgumentException("The radix must be >= 2 and <= " + Digits.Length.ToString());
if (decimalNumber == 0)
return "0";
int index = BitsInLong - 1;
long currentNumber = Math.Abs(decimalNumber);
char[] charArray = new char[BitsInLong];
while (currentNumber != 0)
{
int remainder = (int)(currentNumber % radix);
charArray[index--] = Digits[remainder];
currentNumber = currentNumber / radix;
}
string result = new String(charArray, index + 1, BitsInLong - index - 1);
if (decimalNumber < 0)
{
result = "-" + result;
}
return result;
}
코드가 최적화되지 않았습니다. 샘플 만 있습니다!.
게시일과 상당히 멀다는 것을 알고 있습니다 ... :)
9 개의 Hexa 문자 만 생성하는 생성기가 있습니다. 예 : C9D6F7FF3, C9D6FB52C
public class SlimHexIdGenerator : IIdGenerator
{
private readonly DateTime _baseDate = new DateTime(2016, 1, 1);
private readonly IDictionary<long, IList<long>> _cache = new Dictionary<long, IList<long>>();
public string NewId()
{
var now = DateTime.Now.ToString("HHmmssfff");
var daysDiff = (DateTime.Today - _baseDate).Days;
var current = long.Parse(string.Format("{0}{1}", daysDiff, now));
return IdGeneratorHelper.NewId(_cache, current);
}
}
static class IdGeneratorHelper
{
public static string NewId(IDictionary<long, IList<long>> cache, long current)
{
if (cache.Any() && cache.Keys.Max() < current)
{
cache.Clear();
}
if (!cache.Any())
{
cache.Add(current, new List<long>());
}
string secondPart;
if (cache[current].Any())
{
var maxValue = cache[current].Max();
cache[current].Add(maxValue + 1);
secondPart = maxValue.ToString(CultureInfo.InvariantCulture);
}
else
{
cache[current].Add(0);
secondPart = string.Empty;
}
var nextValueFormatted = string.Format("{0}{1}", current, secondPart);
return UInt64.Parse(nextValueFormatted).ToString("X");
}
}
@dorcohen의 답변과 @pootzko의 의견을 기반으로합니다. 이것을 사용할 수 있습니다. 와이어를 통해 안전합니다.
var errorId = System.Web.HttpServerUtility.UrlTokenEncode(Guid.NewGuid().ToByteArray());
문자열을 입력 할 필요가 없으면 다음을 사용할 수 있습니다.
static class GuidConverter
{
public static string GuidToString(Guid g)
{
var bytes = g.ToByteArray();
var sb = new StringBuilder();
for (var j = 0; j < bytes.Length; j++)
{
var c = BitConverter.ToChar(bytes, j);
sb.Append(c);
j++;
}
return sb.ToString();
}
public static Guid StringToGuid(string s)
=> new Guid(s.SelectMany(BitConverter.GetBytes).ToArray());
}
이렇게하면 Guid가 다음과 같이 8 자 문자열로 변환됩니다.
{b77a49a5-182b-42fa-83a9-824ebd6ab58d}-> "䦥 띺 ᠫ 䋺 ꦃ 亂 檽 趵"
{c5f8f7f5-8a7c-4511-b667-8ad36b446617} --> "엸詼䔑架펊䑫ᝦ"
you can use
code = await UserManager.GenerateChangePhoneNumberTokenAsync(input.UserId, input.MobileNumber);
its 6
nice characters only, 599527
,143354
and when user virify it simply
var result = await UserManager.VerifyChangePhoneNumberTokenAsync(input.UserId, input.Token, input.MobileNumber);
hope this help you
I use the following to create an unique guid(35 characters).
// Example: 7b08e3d-186b-46f0-99c8-e8252033715d
var strUniqueGuid = Guid.NewGuid().ToString();
If you like a unique guid with 16 characters, please use the below code
// Example: 7b08e3d-186b-46f
var strUniqueGuid = Guid.NewGuid().ToString();
strUniqueGuid=strUniqueGuid.Substring(0, 16);
I use Guid.NewGuid().ToString().Split('-')[0]
, it gets the first item from the array separated by the '-'. Its enough to represent a unique key.
Guid.NewGuid().ToString().Split('-').First()
참고URL : https://stackoverflow.com/questions/9278909/net-short-unique-identifier
'programing tip' 카테고리의 다른 글
문자열의 일부를 제거하지만 문자열의 끝에있을 때만 (0) | 2020.11.01 |
---|---|
XML 파일을 읽고 쓰는 방법은 무엇입니까? (0) | 2020.11.01 |
부모 div에서 불투명도를 설정하고 자식 div에 영향을 미치지 않는 방법은 무엇입니까? (0) | 2020.11.01 |
Java에서 임의의 문자열을 생성하는 방법 (0) | 2020.10.31 |
Android에서 ImageView의 최대 너비 및 높이 (0) | 2020.10.31 |