前言:
发文近些年越来越少,这并非自己所愿。但是确实感觉没什么好写的,尤其是工作中遇到的一些问题,如果很容易Google到答案,那我是肯定不会再自己赘述一遍的。再就是感觉工作愈发枯燥,心里也是惴惴不安,如果工作环境,内容,团队,缺乏激情,就应该慎重考虑一下了!这样并不是自己想要的~恰巧工作中遇到的这个问题,解决费了很大功夫,并且Google,Baidu上资料很少,没有找到现成的解决方案,所以就有了此文。以希望后来人遇到此问题时,能检索到此文,给予帮助。
场景:
首先场景时发生在自己写的量化交易客户端软件上,券商交易,要求记录用户操作计算机的IP,网卡MAC地址,硬盘序列号信息。其中IP与网卡MAC地址是很容易获取到的,硬盘序列号其实获取也不难,只不过在低版本Windows系统行就有了坑,比如Windows7,通过相关命令获取到的并不是真正的序列号,而是经过每4位HEX字符经过little endian的总长为40为的字符串。比如:
命令:wmic diskdrive get serialnumber | wmic path win32_physicalmedia get SerialNumber | wmic path Win32_DiskDrive get SerialNumber
结果:32535554574e4741314134313532204a20202020
而通过专业软件获取到的真实硬盘序列号:S2TUNWAGA11425J
解决:
首先用nodejs里的systeminformation组件可以获取到几乎所有硬件信息,当然包括硬盘序列号,但是,Windows7环境下返回的还是如上40位字符串。(Windows10下面是没有任何问题的)
一开始,以为返回的40位字符串『32535554574e4741314134313532204a20202020』为『S2TUNWAGA11425J』的16进制转码。
于是就进行了HEX2ASCII转码,获取到结果:『2SUTWNGA1A4152 J 』。很显然,结果是错误,但是很奇怪的是,字母都是对的,只是顺序各种颠倒。
于是,把正确的序列号转为HEX和结果对比一下:
正确序列号HEX:533254554e5741474131313432354a
命令返回的HEX:32535554574e4741314134313532204a20202020
发现规律了吧!后来在一片帖子中也发现了解说,就是文章开头讲到的规律。接下来要做的就是写个算法,把这40位字符的顺序按照规律,重新给排序回来。然后在进行HEX2ASCII转码就会得到正确的序列号了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
util.getDiskSN = async function () { const data = await systemInfo.diskLayout(); let disCode = data[0].serialNum; if ((os.platform() == 'win32' && os.release().indexOf('6.1') == 0) || disCode.length === 40) { console.log("系统为Windows7!执行特殊命令!"); // excutor.runWithFunc('wmic path win32_physicalmedia get SerialNumber', function (stdoutstr) { // const stdoutstrs = stdoutstr.split('\n'); // window.localStorage.setItem("diskSN", stdoutstrs[1].trim()); // }); const buf = Buffer.from(decodeLittleEndian(disCode), 'hex'); console.log(buf.toString()); window.localStorage.setItem("diskSN", buf.toString().trim()); } else { window.localStorage.setItem("diskSN", disCode); } }; /** * 解决Windows7系统获取硬盘序列号不正确问题 * * @param hexString * @returns {string} */ function decodeLittleEndian(hexString) { let result = ""; for (let i = 0; i < hexString.length / 4; i ++) { const temp = hexString.substr(i * 4, 4); const temp2 = temp.substr(0, 2); const temp3 = temp.substr(2,4); result = result + temp3 + temp2; } return result; } |
至此,Windows7下面获取硬盘序列号的问题就解决了。