[英]How can I write a method that returns an unique string of 6 characters length?
If I do it like this I get some duplicates... 如果我这样做,我会得到一些重复...
private const string _chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987";
public string RandomString(int size)
{
var random = new Random((int)DateTime.Now.Ticks);
Thread.Sleep(random.Next(1, 3));
var buffer = new char[size];
for (int i = 0; i < size; i++)
{
buffer[i] = _chars[random.Next(_chars.Length)];
}
return new string(buffer);
}
The first 100000 request must be unique how can I guarantee it basically... if possible I do not want to keep a list and query it... 第一个100000请求必须是唯一的,我怎么能基本保证...如果可能的话我不想保留一个列表并查询它...
These strings won't overlap over 100,000 iterations because your random number is relatively prime to the larger number. 这些字符串在100,000次迭代中不会重叠,因为您的随机数对于较大的数字而言相对较为重要。 No caching needed.
不需要缓存。
You can run through a random number of iterations before recording the strings to give yourself a larger result space. 在记录字符串之前,您可以运行随机数量的迭代,从而为自己提供更大的结果空间。
If your possible length of random string is limited it would be easiest to use GUIDs: 如果随机字符串的可能长度有限,那么最简单的方法是使用GUID:
A crude implementation might be: 粗略的实施可能是:
public string RandomString(int size)
{
return Guid.NewGuid()
.ToString()
.Replace("-","")
.Substring(0, size);
}
If you need longer then you could concatenate multiple GUID strings together. 如果需要更长时间,则可以将多个GUID字符串连接在一起。
Don't keep a list of all earlier values. 不要保留所有早期值的列表。 Just use a counter.
只需使用一个柜台。
If you want to make the value less predictable (guessable) to a user, use a hash function to scramble the bits before using them. 如果要使值对用户不太可预测(可猜测),请使用哈希函数在使用之前对这些位进行加扰。 But still generate the next input to the hash from a simple counter.
但仍然从一个简单的计数器生成哈希的下一个输入。
If you used an int to represent bit positions, you could do it easily. 如果使用int来表示位位置,则可以轻松完成。
int bits=0
...
while(bitCount(bits)!=6) // Write your own bitCount method--or there is probably one on the net
bits++;
Now you know you have 6 bits in your int, so convert them to the string 现在您知道int中有6位,因此将它们转换为字符串
For instance with your data: 例如,您的数据:
"ABCDEFGHIJKLMNOPQRSTUVWXYZ123654987"
if you were counting and had reached 111111, (The first one you will hit) you'd return "234567", the next one I believe will be 1011111 which will return "134567" then "1101111" which will return "124567". 如果你正在计算并且已达到111111,(你将击中的第一个)你将返回“234567”,我认为下一个将是1011111,它将返回“134567”然后“1101111”将返回“124567”。 (I could be getting the sequence wrong, it's just off the top of my head).
(我可能会把序列弄错,它只是在我的头顶)。
It will always be unique, and the iterating isn't as expensive as you'd think, although you could probably be a bit smarter than just iterating (you could skip large groups if you figured out it was mathematically impossible to reach the next 6-"on" bit number before n increments, or you could just come up with a more straight-forward algorithm to generate the next integer with 6 1's. 它总是独一无二的,并且迭代并不像你想象的那么昂贵,尽管你可能比仅仅迭代更聪明(如果你发现它在数学上不可能达到下一个6,你可以跳过大组) - 在n增量之前的“on”位数,或者你可以想出一个更直接的算法来生成6 1的下一个整数。
You may be able to use current time stamp (milliseconds, microseconds or nannoseconds) (reverse it or change the digit order if you need to show a randomness) and replace the digits in the timestamp number with AZ and 0-9 characters on some criteria. 您可以使用当前时间戳(毫秒,微秒或纳秒)(如果需要显示随机性,则将其反转或更改数字顺序)并在某些条件下将时间戳编号中的数字替换为AZ和0-9个字符。
Otherwise If you don't have any caching mechanism store previously generated values, I think you cannot get random and UNIQUE character sequences. 否则如果您没有任何缓存机制存储以前生成的值,我认为您无法获得随机和UNIQUE字符序列。
If they don't need to be random but only unique then this code works using an odometer type of output. 如果它们不需要是随机的但只是唯一的,则此代码使用里程表类型的输出。
public class Class1
{
List<char> _chars = new List<char>() { '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', '1', '2','3','4', '5', '6', '7', '8', '9', '0' };
private static int[] index = new int[6] {0, 0, 0, 0, 0, 0};
private const int charMax = 35;
public string UniqueString()
{
if (index[5] > charMax)
{
IncromentParent(5);
}
StringBuilder result = new StringBuilder();
result.Append(_chars[index[0]]);
result.Append(_chars[index[1]]);
result.Append(_chars[index[2]]);
result.Append(_chars[index[3]]);
result.Append(_chars[index[4]]);
result.Append(_chars[index[5]]);
index[5]++;
return result.ToString();
}
private void IncromentParent(int active)
{
if (active == 0)
throw new Exception("out of numbers");
int parent = active - 1;
index[active] = 0;
index[parent]++;
if (index[parent] > charMax)
IncromentParent(parent);
}
}
And here is a passing unit test, but it takes a long time to run... 这是一个通过单元测试,但运行需要很长时间...
[TestMethod]
public void MyTestMethod()
{
Class1 target = new Class1();
List<string> results = new List<string>();
for (int i = 0; i < 100000; i++)
{
string result = target.UniqueString();
if (!results.Contains(result))
results.Add(result);
else
Assert.Fail(string.Format("The string '{0}' is already in the list", result));
}
Console.WriteLine(results.Count.ToString());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.