【发布时间】:2013-06-06 23:10:53
【问题描述】:
出于测试目的,我需要生成一个随机字符串,然后将其编码为字节数组以通过 Web 传输并解码回结果字符串。该测试使用 NUnit 框架将原始字符串与结果字符串进行比较。由于编码后的字节数组必须对 Web 友好,所以使用 UTF-8 编码。
字符串被Encoder.GetBytes从UTF8Encoding编码成一个字节数组。字节数组被Decoder.GetChars从UTF8Encoding解码为字符串。
原始字符串需要随机生成,包含任意字符序列,可以使用UTF-8编码进行编码/解码。
我第一次尝试生成字符串是:
public static String RandomString(Random rnd, Int32 length) {
StringBuilder str = new StringBuilder(length);
for (int i = 0; i < length; i++)
str.Append((char)rnd.Next(char.MinValue, char.MaxValue));
return str.ToString();
}
上面的代码产生了带有无效序列的字符串来编码。
在网上找了一些建议,对代码进行了改进:
public static String RandomString(Random rnd, Int32 length) {
StringBuilder str = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = (char)rnd.Next(char.MinValue, char.MaxValue);
while (c >= 0xD800 && c <= 0xDFFF)
c = (char)rnd.Next(char.MinValue, char.MaxValue);
str.Append(c);
return str.ToString();
}
以上代码编码没有问题,但是解码字节数组失败。此外,我不确定代码是否可以涵盖所有可能的情况。
任何建议,如何在 C# 中生成具有给定要求的随机字符串。
UPD:在编码/解码中使用随机字符串:
public static Encoder Utf8Encode = new UTF8Encoding(false, true).GetEncoder();
public static Decoder Utf8Decode = new UTF8Encoding(false, true).GetDecoder();
public unsafe void TestString(Random rnd, int length, byte* byteArray,
int arrayLenght) {
int encodedLen;
String str = RandomString(rnd, length);
fixed (char* pStr = str) {
encodedLen = Utf8Encode.GetBytes(pStr, str.Length, byteArray,
arrayLenght, true);
}
char* buffer = stackalloc char[8192];
int decodedLen = Utf8Decode.GetChars(byteArray, encodedLen, buffer,
8192, true);
String res = new String(buffer, 0, decodedLen);
Assert.AreEqual(str, res);
}
【问题讨论】:
-
我不认为随机字符串是单元测试的好方法,理论上它违反了原则
Repeatable: Tests should produce the same results each time.. every time. Tests should not rely on uncontrollable params。我认为随机测试来自于为边缘情况创建实际测试的懒惰。 -
随机生成器始终使用相同的密封值创建,因此每次测试运行都会产生相同的结果,即测试是可重复的。
-
如果它是一个有效的 Unicode 字符串,你最好只使用 U+0000 和 U+D7FF 之间的值,因为在 U+E000 之上还有其他非法值。无论如何,你说“解码字节数组”。你能显示字节数组吗?您的示例中只有 UTF-16 字符串。
-
对于任何 Unicode 测试,肯定需要高于 U+FFFF 的值。如果只是随机噪声,则将每个字符创建为 0 到 10FFFF 之间的随机元素,并拒绝代理和非字符。 unicode.org/faq/private_use.html#nonchar4 列出了后者的全部 66 个。然后转换为 UTF-8。
-
排除 0xE000 以上的值有助于解决解码失败的问题。
标签: c# string random utf-8 encode