我正在从SetupAPI调用中收集EDID块(作为字节),以获取一些详细的监视器信息。
正如EDID documentation所说,一些字节存储" 5位字母"在他们里面。
为了让您免于头痛,我附上一个方案以便轻松理解:
如您所见,我需要从字节中提取5位字母。
我可以设法将字节分成BitArray,但后来我不知道如何将这些位转换成字母。
Wiki也说:
"00001=A”; “00010=B”; ... “11010=Z”.
那么,转换这些位的最快,最无痛的方法是什么?
我想我可以预定义一个Dictionary对象,如:
Dictionary<BitArray, char> letters = new Dictionary<BitArray, char>();
letters.Add(new BitArray(new int[] { 0, 0, 0, 1 }), Convert.ToChar("A"));
letters.Add(new BitArray(new int[] { 0, 0, 1, 0 }), Convert.ToChar("B"));
然后搜索它,但首先我不知道如何在“00010 = B”到“11010 = Z”之后关注,第二我确定必须有更合适的方式。
感谢您的帮助。
答案 0 :(得分:1)
要回答这个问题,必须理解C#中的位操作和bit&amp;小端机器中的字节布局。一个字节中的位0是最低有效奇数/偶数位,而不是符号位,如果您想将其视为16位数,则第二个字节是位15(符号)到位8,最不重要的是字节。但更重要的是,手头的问题。
在上面的好照片中,#s位是错误的。即使从规范我们可以看到这一点。 EX:“第二个字符(字母)位于位1和0(地址08h)和位7→5(地址09h)”。修正后的图表是: enter image description here
工作代码是(是的,我在我的s / w中使用了这个):
// in 2 bytes, [8,9], ignore top bit then three 5 bit characters
char[] convert = " ABCDEFGHIJKLMNOPQRSTUVWXYZ01234".ToCharArray();
result.AppendFormat("-8: Vendor ID#: {0}{1}{2}\n",
convert[(edid[8] >> 2) & 0x1F],
convert[((edid[8] << 3) & 0x18) | ((edid[9] >> 5) & 0x07)],
convert[edid[9] & 0x1F]);
我剩下的一个问题是,上面字符串中的“01234”应该是什么? 我只使用“01234”作为占位符。它们是未定义的特殊字符($ _- @#),是什么?
答案 1 :(得分:0)
要提取5位的组,可以使用标准的“从比特流中提取东西”技术(它更通用,但没关系),其中一个版本是这样的:(未经过测试,并不是真正意味着代码无论如何,更像是一个低级伪代码)
uint buffer = 0;
int emptybits = 32;
while (want_more_symbols) {
while (emptybits >= 8 && can_read_more) {
emptybits -= 8;
buffer = buffer | ((uint)readByte() << emptybits)
}
int symbol = (int)(buffer >> (32 - 5));
buffer <<= 5;
emptybits += 5;
use(symbol);
}
一般情况下,你可以放置任何东西,包括25,而不是5,它可以是变量。
或者更具体地说,对于这种情况,您可以计算您在数组中查看的位置并直接提取它:(未经测试)
// extract symbol n
int bitindex = n * 5;
int arrayindex = bitindex / 8;
int leftover = bitindex & 7;
if (leftover <= 3)
// it's in one byte
return (array[arrayindex] >> (3 - leftover)) & 32;
else
// crosses byte boundary
return ((array[arrayindex] << (leftover - 3)) |
(array[arrayindex + 1] >> (11 - leftover))) & 32;
要将5位值转换为字母,请将其添加到“A”中。但他们从A = 1开始,所以减去1:
char letter = (char)('A' + x - 1);
答案 2 :(得分:0)
项目:https://github.com/falahati/EDIDParser
NuGet:https://www.nuget.org/packages/EDIDParser
您需要做的就是创建一个提供二进制数据的django-jsonfield
类型的实例,然后使用该类的属性来获取信息,包括供应商的3个字母代码。
EDID
但是,如果您只对从供应商标识号中提取代码的部分感兴趣,可以从此处查看源代码: https://github.com/falahati/EDIDParser/blob/master/EDIDParser/EDID.cs
var edid = new EDID(bytes);
var vendorCode = edid.ManufacturerCode;