From a33ff6cf4fb45f7e880e6fd41cbf8a83369a444b Mon Sep 17 00:00:00 2001 From: zqm Date: Fri, 12 Dec 2025 10:46:27 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E7=94=A8=E5=B7=A5=E5=85=B7=E7=B1=BB?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Windows/CS/Framework4.0/Utils/Utils.ico | Bin 0 -> 5430 bytes Windows/CS/Framework4.0/Utils/Utils.sln | 25 ++ .../Utils/Utils/Properties/AssemblyInfo.cs | 36 +++ Windows/CS/Framework4.0/Utils/Utils/Util.cs | 215 ++++++++++++++++++ .../CS/Framework4.0/Utils/Utils/Utils.csproj | 54 +++++ Windows/CS/Framework4.0/Utils/Utils/Utils.ico | Bin 0 -> 5430 bytes 6 files changed, 330 insertions(+) create mode 100644 Windows/CS/Framework4.0/Utils/Utils.ico create mode 100644 Windows/CS/Framework4.0/Utils/Utils.sln create mode 100644 Windows/CS/Framework4.0/Utils/Utils/Properties/AssemblyInfo.cs create mode 100644 Windows/CS/Framework4.0/Utils/Utils/Util.cs create mode 100644 Windows/CS/Framework4.0/Utils/Utils/Utils.csproj create mode 100644 Windows/CS/Framework4.0/Utils/Utils/Utils.ico diff --git a/Windows/CS/Framework4.0/Utils/Utils.ico b/Windows/CS/Framework4.0/Utils/Utils.ico new file mode 100644 index 0000000000000000000000000000000000000000..e90ab1cd2cfd5d7533bd2bdd10426634b75aa1a7 GIT binary patch literal 5430 zcmeHLdr(x@8DEpW+iBBg+GN^h>R*{8%}f$wj2dH2(%3W+L}L^UC?cR>!1zL*%d)V* z@_sGgvOE=(H@gVy!n%TB1r#v87J0J^$ona8*k8YMajB-_IAj0mv}fkG-@WJF^ZkD3 zeCK}me#_%6<2}b)zMMyPIq&QXJl?B39`6OR?EJtFc)VIVevSI*7TyK|>t{_s{r_+O z-76rndw-*=#fl_vn^oui?bjxI+pHFd_OJb$aaN&@>wfNUw_4=AcjbhK#oK9aU%&My z7MSRhDKS zuI5|48$@dcxsLH?NkCpE_XBH<5&KQ4vkul)Wsq1%yr$&wKC z=-biN-iouSQm6`YFxcCT8#UFax^w}Z+AFwMUydY+xOeB4&psx9%>R<@s}N0@Xn{P(`*(B)O znrZEwAog-bXL}2@H)_z+p@TG14E`~D)K!)v^<*S=Z{Or1l}cY)lAJCu{iXM+3n9@siMAd}X-wz>i$&!Zf=bZua5q`wc*!9Eb2 z_y!tfKH|bes4l;N>==K@gx@|EOqYx73dir;G6`YxBm|_xA-xUTqVK>Yqz0RUuid;(&2e+%fRDvRT z2I_Csf#smcAR!dlY54BiWu(VP;!?33Q?v6NXSv80^IgTL47K9U88TKR4dXbF(g?c*ElywVf~vX+NoiR~ki{Zd8jZxb z2qY#;k&~N+<_0b1CWmk%#RV1q3*3y4!N|>y)5E+L_)}|;GYEw0rxDUV!|6DhtwV9& z6jX$wdlM+6HBfYnL9QR8I53QI$8tThqsXi2Mry|t>PBYKa_2kD4_?Jw@5Lt~llCQx zzvt;X6cT?##|*;sGYHj9<9Lo9>b_}|^iE-WR2>(KgQ-n8kW>#l*=^XyGu+~Iu)XmG z?azhh< zQVa?S=Q{7B;2{|K-R~|uuj-ssVCc%ffpNFcj%9XkpbCnVXpZ0O>`j~>24cEq5ltGR zNP}Bm2Q-7z&6J>)lC?#lU9n=KI!`8yc`LNv_S_1)>yC#VL)FOwG z>v6U?E1Bc>&eC%8m-fu#Bx#7fHwRC7CoT=mE@+@N(DYAHET$gI&2;RL+7l)!D0}2TF0|w;u z%_DB$UI>cJ5B00CtEi}dg->VSygt7tnxqkj0G=6+Pk|JE7z0b~3be%lLe zFMFZuIkG$s0v_)#-vf`%pBCR6I}gD!+FQ>X2?6#$1^ZiKIl=fp#fB&BT*oipeDm;* zw}j4LzvJn)XXPfo^{Q8B=wcJ@TlIXv{?&Vh)+_5hEmvex{rf7r=wtKVZ>WA#ggLF7 zjXS>KR+7i3XVSet>kRzn!>M4$^%p{%KIHx#$q;_FEZE_LH$=AY2YT;)7oL{yjF6Al z{rA5w72B^t_@Q;58_CXvZu#Z;$S?1xBELk8^CxGF{YL9+v&vPl;3I}=*PbAUwV}pq zw!2Ke^7S}UU797Hy)4^>(%2o4`rFSr+U>r&dE>h6>^>Uv3-U4NWwqiT#9eQ1_UC;z zJ568SZ@J~9qqVsqCPakqYO2s)Cr3s6PL#%(LtCvxnApd#&tmIoyR9oeA|E3@``#>P!%S}L1jdF3IUlV4i4Y68{s6kKf!1)R=||ed@jJK3!~z%8QoUYLT8wC#d$~r1@sZ&N zJ_a})(IGyh?;L%@E3j+xCoW8A&mT&RDPYEf2u z>YDCC79le1GW+XR<9KF8UT#52agnGjQ!n~pwF5U7Z<-6OYiDaS^3NoKe|TTe!($(e ze<{$1FOf+?4JC!SsI4l8x+tHUOEIlob-4zqabX6*Q9B9$u+5TnC+XN48R)By4Hpl| zqJs^|vEhaUN$^m7q*yIfKKO1 + /// 通用工具和方法 + /// + public static class Util + { + // CRC16/XMODEM算法实现(带起始位置和长度) + public static ushort CalculateCRC16(byte[] data, int startIndex, int length) + { + ushort crc = 0; + int endIndex = startIndex + length; + for (int i = startIndex; i < endIndex && i < data.Length; i++) + { + crc ^= (ushort)(data[i] << 8); + for (int j = 0; j < 8; j++) + { + if ((crc & 0x8000) != 0) + crc = (ushort)((crc << 1) ^ 0x1021); + else + crc <<= 1; + } + } + return crc; + } + + + + // CRC32-MPEG2算法实现 + public static uint CalculateCRC32(byte[] data) + { + return CalculateCRC32(0xFFFFFFFF, data); + } + + // 支持增量计算的CRC32方法 + public static uint CalculateCRC32(uint crc, byte[] data) + { + uint polynomial = 0x04C11DB7; + + for (int i = 0; i < data.Length; i++) + { + crc ^= (uint)data[i] << 24; + for (int j = 0; j < 8; j++) + { + if ((crc & 0x80000000) != 0) + crc = (crc << 1) ^ polynomial; + else + crc <<= 1; + } + } + return crc; + } + + // 计算文件的CRC32(通过文件路径) + public static uint CalculateFileCRC32(string filePath) + { + using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read)) + { + return CalculateCRC32(fs); + } + } + + // 计算文件的CRC32(通过已打开的文件流) + public static uint CalculateCRC32(FileStream fs) + { + uint crc = 0xFFFFFFFF; + uint polynomial = 0x04C11DB7; + + // 保存当前位置 + long originalPosition = fs.Position; + + try + { + // 重置到文件开头 + fs.Seek(0, SeekOrigin.Begin); + + byte[] buffer = new byte[4096]; + int bytesRead; + + while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0) + { + for (int i = 0; i < bytesRead; i++) + { + crc ^= (uint)buffer[i] << 24; + for (int j = 0; j < 8; j++) + { + if ((crc & 0x80000000) != 0) + crc = (crc << 1) ^ polynomial; + else + crc <<= 1; + } + } + } + } + finally + { + // 恢复到原始位置 + fs.Seek(originalPosition, SeekOrigin.Begin); + } + return crc; + } + + // byte[]转base64编码 + public static string ByteArrayToBase64(byte[] data) + { + return Convert.ToBase64String(data); + } + + // base64转byte[]编码 + public static byte[] Base64ToByteArray(string base64) + { + return Convert.FromBase64String(base64); + } + + // 构建不含前缀的FTPC命令(返回byte[],直接处理字节流) + public static byte[] BuildRawFTPCommand(char command, params object[] parameters) + { + using (MemoryStream ms = new MemoryStream()) + { + // 写入命令(ASCII编码的单个字符) + ms.WriteByte((byte)command); + + // 添加参数(参数之间没有间隔,直接写入字节) + foreach (var param in parameters) + { + if (param is long) + { + // filesize24或addr24: 3字节大端序 + long value = (long)param; + + // 使用位运算直接获取24位值的三个字节,大端序 + byte byte1 = (byte)((value >> 16) & 0xFF); // 最高位字节 + byte byte2 = (byte)((value >> 8) & 0xFF); // 中间字节 + byte byte3 = (byte)(value & 0xFF); // 最低位字节 + + // 直接写入三个字节 + ms.WriteByte(byte1); + ms.WriteByte(byte2); + ms.WriteByte(byte3); + } + else if (param is ushort) + { + // N16: 16位大端序数据长度 + ushort value = (ushort)param; + + // 使用位运算直接获取16位值的两个字节,大端序 + byte byte1 = (byte)((value >> 8) & 0xFF); // 高8位字节 + byte byte2 = (byte)(value & 0xFF); // 低8位字节 + + // 直接写入两个字节 + ms.WriteByte(byte1); + ms.WriteByte(byte2); + } + else if (param is uint) + { + // 处理uint类型(如CRC32值) + uint value = (uint)param; + + // 使用位运算直接获取32位值的四个字节,大端序 + byte byte1 = (byte)((value >> 24) & 0xFF); // 最高位字节 + byte byte2 = (byte)((value >> 16) & 0xFF); // 次高位字节 + byte byte3 = (byte)((value >> 8) & 0xFF); // 次低位字节 + byte byte4 = (byte)(value & 0xFF); // 最低位字节 + + // 直接写入四个字节 + ms.WriteByte(byte1); + ms.WriteByte(byte2); + ms.WriteByte(byte3); + ms.WriteByte(byte4); + } + else if (param is string) + { + // 字符串参数直接写入ASCII字节 + string strValue = (string)param; + byte[] strBytes = Encoding.ASCII.GetBytes(strValue); + ms.Write(strBytes, 0, strBytes.Length); + } + else if (param is byte[]) + { + // byte[]参数直接写入 + byte[] data = (byte[])param; + ms.Write(data, 0, data.Length); + } + } + + // 获取当前流中的所有字节,用于计算CRC16 + byte[] currentBytes = ms.ToArray(); + + // 计算CRC16 + ushort crc16 = CalculateCRC16(currentBytes, 0, currentBytes.Length); + + // 写入CRC16(大端序) + byte crcByte1 = (byte)((crc16 >> 8) & 0xFF); // 高8位 + byte crcByte2 = (byte)(crc16 & 0xFF); // 低8位 + ms.WriteByte(crcByte1); + ms.WriteByte(crcByte2); + + // 返回完整的字节数组 + return ms.ToArray(); + } + } + + // 构建完整通信命令(接受byte[]输入) + public static string BuildCommunicationCommand(byte[] rawFTPCommand) + { + string base64 = Convert.ToBase64String(rawFTPCommand); + return $"set(LFMGR: FTPC, \"{base64}\")"; + } + } +} diff --git a/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj b/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj new file mode 100644 index 0000000..2fcb5cf --- /dev/null +++ b/Windows/CS/Framework4.0/Utils/Utils/Utils.csproj @@ -0,0 +1,54 @@ + + + + + Debug + AnyCPU + {0AAA20B8-F8B1-4C09-ADBF-E6FD650EE9D4} + Library + Properties + JoyD.Windows.CS + Utils + v4.0 + 512 + true + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + bin\Debug\Utils.xml + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + Utils.ico + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Windows/CS/Framework4.0/Utils/Utils/Utils.ico b/Windows/CS/Framework4.0/Utils/Utils/Utils.ico new file mode 100644 index 0000000000000000000000000000000000000000..e90ab1cd2cfd5d7533bd2bdd10426634b75aa1a7 GIT binary patch literal 5430 zcmeHLdr(x@8DEpW+iBBg+GN^h>R*{8%}f$wj2dH2(%3W+L}L^UC?cR>!1zL*%d)V* z@_sGgvOE=(H@gVy!n%TB1r#v87J0J^$ona8*k8YMajB-_IAj0mv}fkG-@WJF^ZkD3 zeCK}me#_%6<2}b)zMMyPIq&QXJl?B39`6OR?EJtFc)VIVevSI*7TyK|>t{_s{r_+O z-76rndw-*=#fl_vn^oui?bjxI+pHFd_OJb$aaN&@>wfNUw_4=AcjbhK#oK9aU%&My z7MSRhDKS zuI5|48$@dcxsLH?NkCpE_XBH<5&KQ4vkul)Wsq1%yr$&wKC z=-biN-iouSQm6`YFxcCT8#UFax^w}Z+AFwMUydY+xOeB4&psx9%>R<@s}N0@Xn{P(`*(B)O znrZEwAog-bXL}2@H)_z+p@TG14E`~D)K!)v^<*S=Z{Or1l}cY)lAJCu{iXM+3n9@siMAd}X-wz>i$&!Zf=bZua5q`wc*!9Eb2 z_y!tfKH|bes4l;N>==K@gx@|EOqYx73dir;G6`YxBm|_xA-xUTqVK>Yqz0RUuid;(&2e+%fRDvRT z2I_Csf#smcAR!dlY54BiWu(VP;!?33Q?v6NXSv80^IgTL47K9U88TKR4dXbF(g?c*ElywVf~vX+NoiR~ki{Zd8jZxb z2qY#;k&~N+<_0b1CWmk%#RV1q3*3y4!N|>y)5E+L_)}|;GYEw0rxDUV!|6DhtwV9& z6jX$wdlM+6HBfYnL9QR8I53QI$8tThqsXi2Mry|t>PBYKa_2kD4_?Jw@5Lt~llCQx zzvt;X6cT?##|*;sGYHj9<9Lo9>b_}|^iE-WR2>(KgQ-n8kW>#l*=^XyGu+~Iu)XmG z?azhh< zQVa?S=Q{7B;2{|K-R~|uuj-ssVCc%ffpNFcj%9XkpbCnVXpZ0O>`j~>24cEq5ltGR zNP}Bm2Q-7z&6J>)lC?#lU9n=KI!`8yc`LNv_S_1)>yC#VL)FOwG z>v6U?E1Bc>&eC%8m-fu#Bx#7fHwRC7CoT=mE@+@N(DYAHET$gI&2;RL+7l)!D0}2TF0|w;u z%_DB$UI>cJ5B00CtEi}dg->VSygt7tnxqkj0G=6+Pk|JE7z0b~3be%lLe zFMFZuIkG$s0v_)#-vf`%pBCR6I}gD!+FQ>X2?6#$1^ZiKIl=fp#fB&BT*oipeDm;* zw}j4LzvJn)XXPfo^{Q8B=wcJ@TlIXv{?&Vh)+_5hEmvex{rf7r=wtKVZ>WA#ggLF7 zjXS>KR+7i3XVSet>kRzn!>M4$^%p{%KIHx#$q;_FEZE_LH$=AY2YT;)7oL{yjF6Al z{rA5w72B^t_@Q;58_CXvZu#Z;$S?1xBELk8^CxGF{YL9+v&vPl;3I}=*PbAUwV}pq zw!2Ke^7S}UU797Hy)4^>(%2o4`rFSr+U>r&dE>h6>^>Uv3-U4NWwqiT#9eQ1_UC;z zJ568SZ@J~9qqVsqCPakqYO2s)Cr3s6PL#%(LtCvxnApd#&tmIoyR9oeA|E3@``#>P!%S}L1jdF3IUlV4i4Y68{s6kKf!1)R=||ed@jJK3!~z%8QoUYLT8wC#d$~r1@sZ&N zJ_a})(IGyh?;L%@E3j+xCoW8A&mT&RDPYEf2u z>YDCC79le1GW+XR<9KF8UT#52agnGjQ!n~pwF5U7Z<-6OYiDaS^3NoKe|TTe!($(e ze<{$1FOf+?4JC!SsI4l8x+tHUOEIlob-4zqabX6*Q9B9$u+5TnC+XN48R)By4Hpl| zqJs^|vEhaUN$^m7q*yIfKKO1