নেট। এ আমার একটি অনন্য শনাক্তকারী দরকার (জিইউইডি এটি ব্যবহার করতে পারে না কারণ এটি এই ক্ষেত্রে বেশ দীর্ঘ)।
লোকেরা কি মনে করে যে এখানে ব্যবহৃত অ্যালগরিদম একজন ভাল প্রার্থী বা আপনার কাছে অন্য কোনও পরামর্শ আছে?
নেট। এ আমার একটি অনন্য শনাক্তকারী দরকার (জিইউইডি এটি ব্যবহার করতে পারে না কারণ এটি এই ক্ষেত্রে বেশ দীর্ঘ)।
লোকেরা কি মনে করে যে এখানে ব্যবহৃত অ্যালগরিদম একজন ভাল প্রার্থী বা আপনার কাছে অন্য কোনও পরামর্শ আছে?
উত্তর:
এটি একটি ভাল - http://www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx
এবং এছাড়াও এখানে ইউটিউবের মতো জিইউইডি
আপনি বেস 64 ব্যবহার করতে পারেন:
string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());
এটি E1HKfn68Pkms5zsZsvKONw == এর মতো একটি স্ট্রিং উত্পন্ন করে। যেহেতু একটি জিইউইডি সর্বদা 128 বিট থাকে তাই আপনি যে == কে জানেন তা সর্বদা শেষে উপস্থিত থাকবেন এবং এটি আপনাকে একটি 22 টি চরিত্রের স্ট্রিং দেবে। এটি যদিও ইউটিউবের মতো ছোট নয়।
আমি ডোর কোহেনের মতো একটি অনুরূপ পন্থা ব্যবহার করি তবে কিছু বিশেষ চরিত্রগুলি মুছে ফেলি:
var uid = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", "");
এটি কেবলমাত্র বর্ণানুক্রমিক অক্ষর আউটপুট করবে। ইউআইডিগুলির সর্বদা একই দৈর্ঘ্য থাকার গ্যারান্টি নেই। এখানে একটি নমুনা রান:
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");
আপনি যখন এই আইডিগুলি উত্পাদন শুরু করবেন তখন থেকে একটি বেসলাইন তারিখ রাখুন (যা এই ক্ষেত্রে 1 লা জানুয়ারী 2016)। এটি আপনার আইডিকে আরও ছোট করে তুলবে।
উত্পন্ন নম্বর: 3af3c14996e54
milliseconds
সেই DateTime
বস্তুর জন্য সর্বদা 0
সাধারণ ব্যবহারযোগ্য প্যাকেজ। আমি এটি অস্থায়ী অনুরোধ আইডি জেনারেটরের জন্য ব্যবহার করি।
https://www.nuget.org/packages/shortid
https://github.com/bolorundurowb/shortid
ব্যবহারসমূহ System.Random
string id = ShortId.Generate();
// id = KXTR_VzGVUoOY
(গিথুব পৃষ্ঠা থেকে)
আপনি নম্বর, বিশেষ অক্ষর এবং দৈর্ঘ্য চান কিনা তা উল্লেখ করে উত্পন্ন আইডির ধরণটি নিয়ন্ত্রণ করতে চান, জেনারেট পদ্ধতিটি কল করুন এবং তিনটি প্যারামিটার পাস করুন, প্রথমটি এমন একটি বুলিয়ান যা আপনি নম্বর চান কিনা তা উল্লেখ করে, দ্বিতীয়টি বুলিয়ান বলেন যে আপনি চান কিনা বিশেষ অক্ষর, আপনার দৈর্ঘ্যের পছন্দকে নির্দেশ করে শেষ সংখ্যা number
string id = ShortId.Generate(true, false, 12);
// id = VvoCDPazES_w
আমি যতদূর জানি, কেবল একটি জিইউইডির কিছু অংশ ছিনিয়ে নেওয়া অনন্য হওয়ার গ্যারান্টিযুক্ত নয় - আসলে এটি অনন্য হওয়া থেকে দূরে।
আমি জানি যে সংক্ষিপ্ততম জিনিসটি যা বিশ্বব্যাপী স্বতন্ত্রতার গ্যারান্টি দেয় তা জেফ আতউডের এই ব্লগ পোস্টটিতে বৈশিষ্ট্যযুক্ত । লিঙ্কযুক্ত পোস্টে, তিনি একটি জিইউডি সংক্ষিপ্ত করার একাধিক উপায় নিয়ে আলোচনা করেন এবং শেষ পর্যন্ত এটি এসকিআই 85 এনকোডিংয়ের মাধ্যমে 20 বাইটে নেমে আসে ।
যাইহোক, যদি আপনার একেবারে এমন কোনও সমাধানের প্রয়োজন হয় যা 15 বাইটের বেশি না হয় তবে আমি ভয় করি যে বিশ্বব্যাপী অনন্য হওয়ার গ্যারান্টিযুক্ত নয় এমন কিছু ব্যবহার করা ছাড়া আপনার আর কোনও উপায় নেই।
পরিচয় মানগুলি একটি ডাটাবেসে স্বতন্ত্র হওয়া উচিত, তবে আপনার সীমাবদ্ধতা সম্পর্কে সচেতন হওয়া উচিত ... উদাহরণস্বরূপ, এটি বাল্ক ডেটা সন্নিবেশকে মূলত অসম্ভব করে তোলে যা আপনি খুব বেশি সংখ্যক রেকর্ডের সাথে কাজ করে থাকলে আপনাকে ধীর করে দেবে।
আপনি একটি তারিখ / সময় মান ব্যবহার করতে সক্ষম হতে পারেন। আমি বেশ কয়েকটি ডাটাবেস দেখেছি যেখানে তারা তারিখ / সময়টি পিকে হওয়ার জন্য ব্যবহার করে এবং যখন এটি সুপার পরিষ্কার না হয় - এটি কাজ করে। আপনি যদি সন্নিবেশগুলি নিয়ন্ত্রণ করেন তবে আপনি কার্যকরভাবে গ্যারান্টি দিতে পারবেন যে মানগুলি কোডের ক্ষেত্রে স্বতন্ত্র।
আমার স্থানীয় অ্যাপ্লিকেশানের জন্য আমি এই সময় ভিত্তিক পদ্ধতির ব্যবহার করছি:
/// <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;
}
এখানে আমার সমাধানটি সমঝোতার জন্য নিরাপদ নয়, প্রতি সেকেন্ডে 1000 গিউডি এর বেশি নয় এবং থ্রেড নিরাপদ।
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;
}
কোডটি অনুকূলিত হয়নি, কেবল নমুনা !.
UtcNow
প্রতি মিলিসেকেন্ডের জন্য একটি অনন্য টিক মান দেয়: মন্তব্য অনুসারে রেজোলিউশনটি সিস্টেম টাইমারের উপর নির্ভর করে। অতিরিক্তভাবে, আপনি আরও নিশ্চিত করে নিতে চাইবেন যে সিস্টেমের ঘড়িটি পিছনে পরিবর্তন হয় না! (যেহেতু ব্যবহারিক 13971889 এর উত্তরটি এই প্রশ্নটি আমার ফিডের শীর্ষে ফেলেছে এবং আমি সেই উত্তরটির সমালোচনা করেছি, আমি অনুভব করি যে আমার এখানে সমালোচনাটি পুনরাবৃত্তি করা উচিত।)
যদি আপনার অ্যাপ্লিকেশনটিতে কয়েক মিলিয়ন লোক না থাকে, সেগুলি একই মিলি সেকেন্ডে সংক্ষিপ্ত অনন্য স্ট্রিং তৈরি করে, আপনি নীচের ফাংশনটি ব্যবহার করার বিষয়ে ভাবতে পারেন।
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 বছরে যদি আপনার অ্যাপ্লিকেশনটি কেবল প্রয়োজন হয় তা হ্যাঁ yyy এ পরিবর্তন করুন।
20160511 আপডেট করুন : সঠিক র্যান্ডম ফাংশন
- লক অবজেক্ট যুক্ত করুন
- এলোমেলো পরিবর্তনশীল র্যান্ডমস্ট্রিং ফাংশন থেকে সরান
রেফ
lock
হ'ল আপনাকে একই Random
উদাহরণটি পুনরায় ব্যবহারের অনুমতি দেওয়া । আমি মনে করি আপনি সেই লাইনটি মুছতে ভুলে গেছেন!
আমি জানি এটি পোস্টের তারিখ থেকে অনেক দূরে ... :)
আমার একটি জেনারেটর রয়েছে যা কেবলমাত্র 9 টি হেক্সা অক্ষর তৈরি করে , যেমন: 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");
}
}
@ ডোরকোহেন এর উত্তর এবং @ pootzko এর মন্তব্যের ভিত্তিতে। আপনি এটি ব্যবহার করতে পারেন। এটি তারের ওপরে নিরাপদ।
var errorId = System.Web.HttpServerUtility.UrlTokenEncode(Guid.NewGuid().ToByteArray());
Jzhw2oVozkSNa2IkyK4ilA2
অথবা নিজের এ চেষ্টা dotnetfiddle.net/VIrZ8j
কিছু অন্যের উপর ভিত্তি করে, এখানে আমার সমাধান যা একটি পৃথক এনকোডযুক্ত নির্দেশনা সরবরাহ করে যা ইউআরএল (এবং ডকার) নিরাপদ এবং কোনও তথ্য আলগা করে না:
Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("=", "").Replace("+", "-").Replace("/", "_");
উদাহরণ ফলাফল:
BcfttHA780qMdHSxSBoZFA
_4p5srPgOE2f25T_UnoGLw
H9xR_zdfm0y-zYjdR3NOig
সি # তে একটি long
মান 64 বিট থাকে, যা বেস 64 এর সাথে এনকোড করা থাকলে 1 প্যাডিং সহ 12 টি অক্ষর থাকবে =
। আমরা যদি প্যাডিংটি ছাঁটাই করি তবে =
11 টি অক্ষর থাকবে।
এখানে একটি উন্মাদ ধারণাটি হ'ল আমরা ইউনিক্স ইপচের সংমিশ্রণ এবং একটি মান রূপের জন্য একটি যুগের জন্য একটি কাউন্টার ব্যবহার করতে পারি long
। ইউনিক্স পর্ব সি # DateTimeOffset.ToUnixEpochMilliseconds
হয় long
ফরম্যাট, কিন্তু 8 বাইট প্রথম 2 বাইট সবসময় 0 হয়, কারণ অন্যথায় তারিখ সময় মান সর্বাধিক তারিখ সময় মানের চেয়ে অনেক বেশি হবে। যাতে আমাদের একটি ushort
কাউন্টার স্থাপন 2 বাইট দেয় ।
সুতরাং, মোট হিসাবে, যতক্ষণ না আইডি উত্পাদনের সংখ্যা প্রতি মিলিসেকেন্ডে 65536 এর বেশি না হয়, আমাদের একটি অনন্য আইডি থাকতে পারে:
// This is the counter for current epoch. Counter should reset in next millisecond
ushort currentCounter = 123;
var epoch = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// Because epoch is 64bit long, so we should have 8 bytes
var epochBytes = BitConverter.GetBytes(epoch);
if (BitConverter.IsLittleEndian)
{
// Use big endian
epochBytes = epochBytes.Reverse().ToArray();
}
// The first two bytes are always 0, because if not, the DateTime.UtcNow is greater
// than DateTime.Max, which is not possible
var counterBytes = BitConverter.GetBytes(currentCounter);
if (BitConverter.IsLittleEndian)
{
// Use big endian
counterBytes = counterBytes.Reverse().ToArray();
}
// Copy counter bytes to the first 2 bytes of the epoch bytes
Array.Copy(counterBytes, 0, epochBytes, 0, 2);
// Encode the byte array and trim padding '='
// e.g. AAsBcTCCVlg
var shortUid = Convert.ToBase64String(epochBytes).TrimEnd('=');
public static string ToTinyUuid(this Guid guid)
{
return Convert.ToBase64String(guid.ToByteArray())[0..^2] // remove trailing == padding
.Replace('+', '-') // escape (for filepath)
.Replace('/', '_'); // escape (for filepath)
}
ব্যবহার
Guid.NewGuid().ToTinyUuid()
পিছনে রূপান্তর করা রকেট বিজ্ঞান নয়, তাই আমি আপনাকে অনেক কিছু ছেড়ে দেব।
আপনার যদি স্ট্রিং টাইপ করতে না চান তবে আপনি নিম্নলিখিতটি ব্যবহার করতে পারেন:
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());
}
এটি গাইডকে এই জাতীয় 8 টি চরিত্রের স্ট্রিংয়ে রূপান্তর করবে:
{b77a49a5-182b-42fa-83a9-824ebd6ab58d> -> "䦥 띺 ᠫ 䋺 ꦃ 亂 檽 趵"
{c5f8f7f5-8a7c-4511-b667-8ad36b446617} -> " 엸 詼 䔑 架 펊 䑫 䑫"
এলোমেলো এবং সংক্ষিপ্ত অনন্য আইডি উত্পন্ন করার জন্য আমার ছোট পদ্ধতিটি এখানে। সুরক্ষিত এলোমেলো সংখ্যা জেনারেশনের জন্য একটি ক্রিপ্টোগ্রাফিক আরএনজি ব্যবহার করে। আপনার chars
স্ট্রিংয়ে যা অক্ষর দরকার তা যুক্ত করুন ।
private string GenerateRandomId(int length)
{
char[] stringChars = new char[length];
byte[] randomBytes = new byte[length];
using (RandomNumberGenerator rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomBytes);
}
string chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < stringChars.Length; i++)
{
stringChars[i] = chars[randomBytes[i] % chars.Length];
}
return new string(stringChars);
}
অক্ষরগুলি (+ / -) না হারাতে এবং যদি আপনি কোনও url- এ আপনার গাইড ব্যবহার করতে চান তবে এটি অবশ্যই বেস 32 এ রূপান্তরিত হতে হবে
10 000 000 এর জন্য কোনও সদৃশ কী নেই
public static List<string> guids = new List<string>();
static void Main(string[] args)
{
for (int i = 0; i < 10000000; i++)
{
var guid = Guid.NewGuid();
string encoded = BytesToBase32(guid.ToByteArray());
guids.Add(encoded);
Console.Write(".");
}
var result = guids.GroupBy(x => x)
.Where(group => group.Count() > 1)
.Select(group => group.Key);
foreach (var res in result)
Console.WriteLine($"Duplicate {res}");
Console.WriteLine($"*********** end **************");
Console.ReadLine();
}
public static string BytesToBase32(byte[] bytes)
{
const string alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
string output = "";
for (int bitIndex = 0; bitIndex < bytes.Length * 8; bitIndex += 5)
{
int dualbyte = bytes[bitIndex / 8] << 8;
if (bitIndex / 8 + 1 < bytes.Length)
dualbyte |= bytes[bitIndex / 8 + 1];
dualbyte = 0x1f & (dualbyte >> (16 - bitIndex % 8 - 5));
output += alphabet[dualbyte];
}
return output;
}
আপনি নিম্নলিখিত লাইব্রেরি দিয়ে চেষ্টা করতে পারেন:
private static readonly object _getUniqueIdLock = new object();
public static string GetUniqueId()
{
lock(_getUniqueIdLock)
{
System.Threading.Thread.Sleep(1);
return DateTime.UtcNow.Ticks.ToString("X");
}
}
UtcNow
প্রতি মিলিসেকেন্ডের জন্য একটি অনন্য টিক মান দেয়: মন্তব্য অনুসারে রেজোলিউশনটি সিস্টেম টাইমারের উপর নির্ভর করে। অতিরিক্তভাবে, আপনি আরও নিশ্চিত করে নিতে চাইবেন যে সিস্টেমের ঘড়িটি পিছনে পরিবর্তন হয় না! (ur3an0 এর উত্তরেও এই সমস্যাগুলি রয়েছে))
তুমি ব্যবহার করতে পার
code = await UserManager.GenerateChangePhoneNumberTokenAsync(input.UserId, input.MobileNumber);
এটির 6
সুন্দর চরিত্রগুলি কেবল 599527
,143354
এবং যখন ব্যবহারকারী এটি সহজভাবে নিখুঁত
var result = await UserManager.VerifyChangePhoneNumberTokenAsync(input.UserId, input.Token, input.MobileNumber);
আশা করি এটি আপনাকে সাহায্য করবে
Guid.NewGuid().ToString().Split('-').First()