0

I have a request table that requires a unique string Id to be displayed for the users.

After some searches I found Kevin's post that perfectly worked for me. here

But when the request started to have an id of 4 digit (ex. 5041), I get an IndexOutOfRangeException error. How is that possible? And how can I fix it?

    private static Random random = new Random();
    private static int largeCoprimeNumber = 502277;
    private static int largestPossibleValue = 1679616;

    private static char[] Base36Alphabet = new char[] { '0','1','2','3','4','5','6','7','8','9',
    'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };

    public static string GetTicket(int id)
    {
        int adjustedID = id * largeCoprimeNumber % largestPossibleValue;
        string ticket = IntToString(adjustedID);

        while (ticket.Length < 4)  
            ticket = "0" + ticket;

        return ticket + new string(Enumerable.Repeat(Base36Alphabet, 6).Select(s => s[random.Next(s.Length)]).ToArray());
    }

    private static string IntToString(int value)
    {
        string result = string.Empty;
        int targetBase = Base36Alphabet.Length;

        do
        {
            result = Base36Alphabet[value % targetBase] + result;
            value = value / targetBase;
        }
        while (value > 0);

        return result;
    }

Calling the GetTicket method:

     Request request = new Request()
     {
         //properties
     };
     _db.Request.Add(request);
     await _db.SaveChangesAsync();
    request.TicketId = GetTicket(request.Id);
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
roo
  • 129
  • 1
  • 1
  • 14

1 Answers1

1

The answer is: when you multiply the answer is larger than the int.Max - that causes the number to be a negative. The solution is to change the type to long.

Here is tested code:

 private static Random random = new Random();
    private static long largeCoprimeNumber = 502277;
    private static long largestPossibleValue = 1679616;
    private static char[] Base36Alphabet = new char[] { '0','1','2','3','4','5','6','7','8','9',
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };

    public static string GetTicket(long id)
    {
        long adjustedID = (id * largeCoprimeNumber) % largestPossibleValue;
        string ticket = LongToString(adjustedID);
        while (ticket.Length < 4) ticket = "0" + ticket;
        return ticket + new string(Enumerable.Repeat(Base36Alphabet, 6).Select(s => s[random.Next(s.Length)]).ToArray());
    }

    private static string IntToString(int value)
    {
        string result = string.Empty;
        int targetBase = Base36Alphabet.Length;
        do
        {
            result = Base36Alphabet[value % targetBase] + result;
            value = value / targetBase;
        }
        while (value > 0);

        return result;
    }

    private static string LongToString(long value)
    {
        string result = string.Empty;
        int targetBase = Base36Alphabet.Length;
        do
        {
            result = Base36Alphabet[value % targetBase] + result;
            value = value / targetBase;
        }
        while (value > 0);

        return result;
    }