.NET Short Unique Identifier


93

ฉันต้องการตัวระบุที่ไม่ซ้ำกันใน. NET (ไม่สามารถใช้ GUID ได้เนื่องจากยาวเกินไปสำหรับกรณีนี้)

ผู้คนคิดว่าอัลกอริทึมที่ใช้ที่นี่เป็นตัวเลือกที่ดีหรือคุณมีข้อเสนอแนะอื่น ๆ หรือไม่?


6
สั้นแค่ไหน? และมีเอกลักษณ์อย่างไร? GUID รับประกันว่าจะไม่ซ้ำกันหากขึ้นอยู่กับที่อยู่ฮาร์ดแวร์ของอะแดปเตอร์อีเธอร์เน็ต สิ่งใดก็ตามที่สร้างขึ้นทางคณิตศาสตร์อย่างหมดจดไม่สามารถพิสูจน์ได้ว่าเป็นเอกลักษณ์ - อาจเป็นเอกลักษณ์ (มีความเป็นไปได้สูงทางดาราศาสตร์)
จอน

ความยาว 15 และมีเอกลักษณ์ (น่าจะ) มากที่สุด
Noel

4
var สุ่ม = 4; // ดีพอ
KristoferA

5
15 อะไรยาว? 15 ไบต์? ถ้าเป็นเช่นนั้นทำไมไม่เพียงแค่ตัดไบต์ออกจาก guid .. ?
KristoferA

3
การลอกออกหนึ่งไบต์ในคู่มือทางดาราศาสตร์ทำให้คุณมีโอกาสเกิดการชนกันที่สำคัญ หากคุณตัดไบต์ที่เรียงลำดับไม่ถูกต้องอาจทำให้เกิดการชนกันได้
Chris Marisic

คำตอบ:


101

อันนี้ดี - http://www.singular.co.nz/blog/archive/2007/12/20/shortguid-a-shorter-and-url-friendly-guid-in-c-sharp.aspx

และนี่ คือ GUID ที่เหมือน YouTube

คุณสามารถใช้ Base64:

string base64Guid = Convert.ToBase64String(Guid.NewGuid().ToByteArray());

ที่สร้างสตริงเช่น E1HKfn68Pkms5zsZsvKONw == เนื่องจาก GUID เป็น 128 บิตเสมอคุณจึงสามารถละเว้น == ที่คุณรู้ว่าจะปรากฏในตอนท้ายเสมอและจะให้สตริงอักขระ 22 ตัว นี่ไม่สั้นเท่า YouTube


12
หมายเหตุสั้น ๆ : หากจำเป็นสำหรับ URL ใครก็ตามที่ใช้สิ่งนี้อาจต้องการทำความสะอาดอักขระ "+" และ "/" ด้วย
tkit


1
ฉันต้องการรหัสเฉพาะยาวสูงสุด 23 ตัวสำหรับ UnnyNet ใน Unity และฉันติดอยู่กับ GUID ที่โง่เขลาของฉันและคุณทำให้ฉันมีความสุขมาก :)
nipunasudha

ที่น่าสนใจ (ถ้าคุณกำลังทำงานกับ Zoom API) นี่เป็นวิธีที่พวกเขาสร้าง UUID ของพวกเขา มีความยาว 22 อักขระและเข้ารหัส base64
vgel

40

ฉันใช้วิธีการที่คล้ายกันกับ Dor Cohen แต่ลบอักขระพิเศษบางตัว:

var uid = Regex.Replace(Convert.ToBase64String(Guid.NewGuid().ToByteArray()), "[/+=]", "");     

สิ่งนี้จะแสดงเพียงอักขระที่เป็นตัวเลขและตัวอักษร UID ไม่รับประกันว่าจะมีความยาวเท่ากันเสมอไป นี่คือตัวอย่างการทำงาน:

vmKo0zws8k28fR4V4Hgmw 
TKbhS0G2V0KqtpHOU8e6Ug 
rfDi1RdO0aQHTosh9dVvw
3jhCD75fUWjQek8XRmMg 
CQUg1lXIXkWG8KDFy7z6Ow 
bvyxW5aj10OmKA5KMhppw
pIMK8eq5kyvLK67xtsIDg
VX4oljGWpkSQGR2OvGoOQ 
NOHBjUUHv06yIc7EvotRg
iMniAuUG9kiGLwBtBQByfg

7
คุณจะสูญเสียคุณสมบัติบางอย่างที่รับประกันโดย GUID โดยการทิ้งข้อมูลเช่นนี้ ฉันขอแนะนำให้แทนที่อักขระที่คุณไม่คุ้นเคยด้วยอักขระอื่นในขณะที่รักษา bijection ระหว่าง GUID และรูปแบบการจัดลำดับ
LukášLánský

3
นี่เป็นวิธีที่ดีที่จะใช้หากคุณไม่ต้องการแปลงกลับเป็น GUID แต่เพียงแค่ต้องการอักขระแบบสุ่มสำหรับอย่างอื่น .. ตัวอย่างเช่นการติดตามคนงานในหลายเธรดหรือคำนำหน้าการบันทึกสำหรับวัตถุที่มีเธรดเป็นต้น
Piotr Kula

24
var ticks = new DateTime(2016,1,1).Ticks;
var ans = DateTime.Now.Ticks - ticks;
var uniqueId = ans.ToString("x");

กำหนดวันที่พื้นฐาน (ซึ่งในกรณีนี้คือ 1 มกราคม 2016) นับจากวันที่คุณจะเริ่มสร้างรหัสเหล่านี้ วิธีนี้จะทำให้รหัสของคุณเล็กลง

หมายเลขที่สร้างขึ้น: 3af3c14996e54


millisecondsเป็น 0 สำหรับDateTimeวัตถุนั้นเสมอ
Teejay

ลบประโยคสุดท้ายด้วย
Teejay

1
oneliner: var uniqueId = (DateTime.Now.Ticks - DateTime ใหม่ (2016, 1, 1) .Ticks) .ToString ("x");
Sgedda

7
ไม่ดีสำหรับการสร้างรหัสเกือบในเวลาเดียวกันเช่นใน for-loop.eg dotnetfiddle.net/L3MIgZ
Jaider

17

แพ็คเกจที่ใช้งานง่าย ฉันใช้มันเพื่อสร้าง 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

11

เท่าที่ฉันรู้การลอกส่วนหนึ่งของ GUID ไม่ได้รับประกันว่าจะไม่ซ้ำใคร แต่ในความเป็นจริงมันยังห่างไกลจากความเป็นเอกลักษณ์

สิ่งที่สั้นที่สุดที่ฉันรู้ว่าการค้ำประกันเอกลักษณ์ทั่วโลกให้ความสำคัญในบล็อกโพสต์นี้โดย Jeff Atwood ในโพสต์ที่เชื่อมโยงเขากล่าวถึงหลายวิธีในการทำให้ GUID สั้นลงและในที่สุดก็ลดลงเหลือ 20 ไบต์ผ่านการเข้ารหัส Ascii85การเข้ารหัส

อย่างไรก็ตามหากคุณต้องการโซลูชันที่มีความยาวไม่เกิน 15 ไบต์อย่างแน่นอนฉันเกรงว่าคุณจะไม่มีทางเลือกอื่นนอกจากใช้สิ่งที่ไม่รับประกันว่าจะไม่ซ้ำกันทั่วโลก


6

ค่า IDENTITY ควรไม่ซ้ำกันในฐานข้อมูล แต่คุณควรตระหนักถึงข้อ จำกัด ... ตัวอย่างเช่นทำให้การแทรกข้อมูลจำนวนมากเป็นไปไม่ได้โดยทั่วไปซึ่งจะทำให้คุณทำงานช้าลงหากคุณกำลังทำงานกับระเบียนจำนวนมาก

คุณอาจใช้ค่าวันที่ / เวลาได้ด้วย ฉันเคยเห็นฐานข้อมูลหลายแห่งที่พวกเขาใช้วันที่ / เวลาเป็น PK และแม้ว่ามันจะไม่สะอาดมาก แต่ก็ใช้งานได้ หากคุณควบคุมส่วนแทรกคุณสามารถรับประกันได้อย่างมีประสิทธิภาพว่าค่าจะไม่ซ้ำกันในโค้ด


6

สำหรับแอปในพื้นที่ของฉันฉันใช้วิธีการตามเวลานี้:

/// <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;
}

3

ที่นี่วิธีแก้ปัญหาของฉันไม่ปลอดภัยสำหรับการทำงานพร้อมกันไม่เกิน 1,000 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;
    }

รหัสไม่ได้รับการปรับให้เหมาะสมเพียงแค่ตัวอย่าง!.


ในขณะที่วิธีแก้ปัญหาที่น่าสนใจไม่มีการรับประกันว่าUtcNowจะส่งคืนค่าติ๊กที่ไม่ซ้ำกันสำหรับทุก ๆ มิลลิวินาที: ตามข้อสังเกตความละเอียดขึ้นอยู่กับตัวจับเวลาของระบบ นอกจากนี้คุณควรตรวจสอบให้แน่ใจว่านาฬิการะบบไม่เปลี่ยนย้อนกลับ! (เนื่องจากคำตอบของ user13971889 ทำให้คำถามนี้อยู่ด้านบนสุดของฟีดของฉันและฉันก็วิจารณ์คำตอบนั้นฉันคิดว่าฉันควรจะวิจารณ์ซ้ำที่นี่)
โจซีเวลล์

3

หากแอปของคุณไม่มีผู้ใช้เพียงไม่กี่ล้านคนโดยใช้ที่สร้างสตริงสั้น ๆ ที่ไม่ซ้ำกันที่ SAME 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());
}

เปลี่ยน yyyy เป็น yy หากคุณต้องการใช้แอพของคุณใน 99 ปีถัดไป
อัปเดต 20160511 : แก้ไขฟังก์ชันสุ่ม
- เพิ่มวัตถุล็อค
- ย้ายตัวแปรสุ่มออกจากฟังก์ชัน RandomString
อ้างอิง


2
วิธีนี้ดีมากแม้ว่าคุณจะไม่ควรเริ่มการสุ่มใหม่ทุกครั้ง - เหตุผลในlockการอนุญาตให้คุณใช้Randomอินสแตนซ์เดิมซ้ำได้ ฉันคิดว่าคุณลืมลบบรรทัดนั้น!
NibblyPig

1

ฉันรู้ว่ามันค่อนข้างไกลจากวันที่โพสต์ ... :)

ฉันมีเครื่องกำเนิดไฟฟ้าที่สร้างอักขระ Hexaเพียง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");
    }
}

1

จากคำตอบของ @dorcohen และความคิดเห็นของ @ pootzko คุณสามารถใช้สิ่งนี้ ปลอดภัยกว่าสายไฟ

var errorId = System.Web.HttpServerUtility.UrlTokenEncode(Guid.NewGuid().ToByteArray());

ผลลัพธ์ถ้าใครสงสัย: Jzhw2oVozkSNa2IkyK4ilA2หรือลองด้วยตัวเองที่dotnetfiddle.net/VIrZ8j
chriszo111

1

จากข้อมูลอื่น ๆ นี่คือโซลูชันของฉันซึ่งมี guid ที่เข้ารหัสที่แตกต่างกันซึ่งเป็น URL (และ Docker) ที่ปลอดภัยและไม่สูญเสียข้อมูลใด ๆ :

Convert.ToBase64String(Guid.NewGuid().ToByteArray()).Replace("=", "").Replace("+", "-").Replace("/", "_");

ตัวอย่างผลลัพธ์คือ:

BcfttHA780qMdHSxSBoZFA
_4p5srPgOE2f25T_UnoGLw
H9xR_zdfm0y-zYjdR3NOig

มันแทนที่อักขระบางตัวด้วยทางเลือกที่ทำงานในสถานการณ์ที่จำเป็นต้องใช้ค่าสำหรับ URL หรือชื่อ Docker เมื่อแทนที่คุณจะไม่สูญเสียข้อมูลใด ๆ
Roemer

1

ใน C # longคุ้มค่ามี 64 บิตซึ่งถ้าเข้ารหัสด้วย Base64 จะมี 12 ตัวอักษรรวมทั้ง 1 =padding หากเราตัดแต่งช่องว่าง=ภายในจะมีอักขระ 11 ตัว

แนวคิดบ้าๆอย่างหนึ่งคือเราสามารถใช้การรวมกันของ Unix Epoch และตัวนับสำหรับค่ายุคหนึ่งเพื่อสร้างlongมูลค่าได้ Unix Epoch ใน C # DateTimeOffset.ToUnixEpochMillisecondsอยู่ในlongรูปแบบ แต่ 2 ไบต์แรกของ 8 ไบต์จะเป็น 0 เสมอเพราะไม่เช่นนั้นค่าวันที่เวลาจะมากกว่าค่าวันที่เวลาสูงสุด นั่นทำให้เรา 2 ไบต์ในการวางushortเคาน์เตอร์

ดังนั้นโดยรวมตราบใดที่จำนวนการสร้าง ID ไม่เกิน 65536 ต่อมิลลิวินาทีเราสามารถมี ID เฉพาะได้:

// 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('=');

1
    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()

ไม่ใช่วิทยาศาสตร์จรวดที่จะแปลงกลับดังนั้นฉันจะปล่อยให้คุณมากขนาดนั้น


0

หากคุณไม่จำเป็นต้องพิมพ์สตริงคุณสามารถใช้สิ่งต่อไปนี้:

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} -> "엸詼䔑架펊䑫ᝦ"


0

นี่คือวิธีการเล็ก ๆ ของฉันในการสร้าง id เฉพาะแบบสุ่มและสั้น ๆ ใช้ rng การเข้ารหัสเพื่อการสร้างตัวเลขสุ่มที่ปลอดภัย เพิ่มอักขระที่คุณต้องการลงใน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);
}

0

เพื่อไม่ให้ตัวละครหายไป (+ / -) และหากคุณต้องการใช้ guid ของคุณใน url จะต้องเปลี่ยนเป็น base32

สำหรับ 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;
    }


0

22 ตัวอักษร, url ปลอดภัยและรักษาความเป็นเอกลักษณ์ของ Guid

// Our url safe, base 64 alphabet:
const string alphabet = "-_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";

// Sanitized Guid string. Preserve the last two hex chars
var guidStr = "929F7C4D4B2644E1A122A379C02D6345";
var lastTwo = guidStr.Substring(30, 2);

string shortGuid = "";

// Iterate over the ten groups of 3 hex chars: 929 F7C 4D4 B26 44E 1A1 22A 379 C02 D63
for (var i = 0; i < 10; i++)
{
    var hex = guidStr.Substring(i*3, 3);              // Get the next 3 hex chars
    var x = Convert.ToInt32(hex, 16);                 // Convert to int
    shortGuid += $"{alphabet[x/64]}{alphabet[x%64]}"; // Lookup the two-digit base64 value
}
shortGuid += lastTwo; // Don't forget the last two

Console.WriteLine(shortGuid);

เอาท์พุต:

yDXWhiGAfc4v6EbTK0Px45

ไม่ใช่ผู้โหวตลงคะแนน แต่ไม่แน่ใจว่าสิ่งนี้แตกต่างจากคำตอบที่ยอมรับอย่างไรมันเป็นเพียงวิธีที่แตกต่างโดยไม่ต้องแปลงเป็น Base64 อย่างชัดเจน
phuzi

1
เจตนาของฉันคือการจัดหาโซลูชันที่แสดงอัลกอริทึม มีหลายวิธีที่มีบรรทัดโค้ดน้อยลงอย่างชัดเจน แต่เป็นเรื่องดีเสมอที่จะรู้ว่าบางสิ่งบางอย่างทำงานอย่างไร โซลูชันนี้สามารถพกพาไปยังภาษาอื่น ๆ ได้อย่างง่ายดาย
Didaxis

0

ในกรณีที่การลบยัติภังค์จะทำเพื่อใครก็ได้:

Guid.NewGuid().ToString("n")

สิ่งนี้สร้างสตริงที่ไม่ซ้ำกันอย่างสมบูรณ์ 32 อักขระ:

5db4cee3bfd8436395d37fca2d48d5b3
82fac271c76148a3a0667c00a5da990d

-2

คุณสามารถใช้ได้

code = await UserManager.GenerateChangePhoneNumberTokenAsync(input.UserId, input.MobileNumber);

ของ6ตัวละครที่ดีเท่านั้น599527,143354

และเมื่อผู้ใช้พิสูจน์มันง่ายๆ

var result = await UserManager.VerifyChangePhoneNumberTokenAsync(input.UserId, input.Token, input.MobileNumber);

หวังว่านี่จะช่วยคุณได้


ฉันเก็บรหัสผ่านที่เรียบง่ายและจำง่ายอยู่เสมอ
Toolkit

-2
private static readonly object _getUniqueIdLock = new object();
public static string GetUniqueId()
{       
    lock(_getUniqueIdLock)
    {
        System.Threading.Thread.Sleep(1);
        return DateTime.UtcNow.Ticks.ToString("X");
    }
}

1
ในขณะที่วิธีแก้ปัญหาที่น่าสนใจไม่มีการรับประกันว่าUtcNowจะส่งคืนค่าติ๊กที่ไม่ซ้ำกันสำหรับทุก ๆ มิลลิวินาที: ตามข้อสังเกตความละเอียดขึ้นอยู่กับตัวจับเวลาของระบบ นอกจากนี้คุณควรตรวจสอบให้แน่ใจว่านาฬิการะบบไม่เปลี่ยนย้อนกลับ! (คำตอบของ ur3an0 ก็มีปัญหาเหล่านี้เช่นกัน)
Joe Sewell

เห็นด้วย นี่เป็นแนวทางของผู้ชายที่น่าสงสารและไม่ควรใช้นอกเหนือจากสภาพแวดล้อมที่คุณควบคุมได้ดี
user13971889

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.