You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

337 lines
11 KiB
C#

9 months ago
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace POSV.Utils
{
/// <summary>
/// M1卡功能类
/// </summary>
public class MifareCardUtils
{
private static byte[] KEY_A = { 0x6F, 0x82, 0xD7, 0x20, 0xD9, 0x4B };
private static byte[] KEY_Other = { 0x46 , 0x46 , 0x46 , 0x46 , 0x46 , 0x46 };
private static string PASSWD = "AE302A12B644A790A22E53F13BCC4AB8";
public static int Init(Int16 port , int baud)
{
return Mwrf32_Init(port , baud);
}
public static int Status(int handle)
{
return Mwrf32_Status(handle);
}
public static void Beep(int handle , int msec)
{
Mwrf32_Beep(handle , msec);
}
public static Tuple<int , string> Card(int handle)
{
return Mwrf32_Card(handle);
}
public static Tuple<int , string> Read(int handle , int mode , int sector , int block)
{
return Mwrf32_Read(handle , mode , sector , block);
}
public static Tuple<int, string> Read_Other(int handle, int mode, int sector, int block)
{
return Mwrf32_Read_Other(handle, mode, sector, block);
}
public static int Halt(int handle)
{
return Mwrf32_Halt(handle);
}
public static int Exit(int handle)
{
return Mwrf32_Exit(handle);
}
/// <summary>
/// 获取卡片序列号
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
public static string GetSnr(int handle)
{
byte[] snr = new byte[5];
//开始寻卡0——表示IDLE模式一次只对一张卡操作
int status = Mwrf32.rf_card(handle, 1, snr);
if (status == 0)
{
NLog.LogManager.GetCurrentClassLogger().Info(ByteArrayToHexString(snr));
return ByteArrayToHexString(snr);
}
else
{
return "";
}
}
/// <summary>
/// 明华RF-EYE-U010-MEM 读卡器初始化
/// 型号RF-EYE-U010-MEM
/// 批号12520169920
/// </summary>
/// <returns></returns>
private static int Mwrf32_Init(Int16 port , int baud)
{
return Mwrf32.rf_init(port , baud);
}
/// <summary>
/// 取得硬件版本号
/// </summary>
/// <param name="handle"></param>
/// <param name="state"></param>
/// <returns></returns>
private static int Mwrf32_Status(int handle)
{
byte[] version = new byte[30];
return Mwrf32.rf_get_status(handle , version);
}
/// <summary>
/// 蜂鸣
/// </summary>
/// <param name="handle"></param>
/// <param name="msec"></param>
private static void Mwrf32_Beep(int handle , int msec)
{
Mwrf32.rf_beep(handle , msec);
}
private static Tuple<int , string> Mwrf32_Card(int handle)
{
byte[] snr = new byte[5];
//开始寻卡0——表示IDLE模式一次只对一张卡操作
int status = Mwrf32.rf_card(handle , 1 , snr);
if (status == 0)
{
byte[] snr1 = new byte[8];
Mwrf32.hex_a(snr , snr1 , 4);
NLog.LogManager.GetCurrentClassLogger().Debug("检测到会员卡:" + System.Text.Encoding.Default.GetString(snr1));
return new Tuple<int, string>(status, System.Text.Encoding.Default.GetString(snr1));
}
else
{
return new Tuple<int , string>(status , string.Empty);
}
}
private static Tuple<int, string> Mwrf32_Read(int handle , int mode , int sector , int block)
{
int status = Mwrf32.rf_load_key(handle , mode , sector , KEY_A);
if (status == 0)
{
status = Mwrf32.rf_authentication(handle , 0 , sector); //验证密码
if (status == 0)
{
byte[] buffer = new byte[16];
status = Mwrf32.rf_read(handle , sector * 4 + block , buffer); //读数据
if (status == 0)
{
string _message = "";
for (int i = 0; i < 4 * 4; i++)
{
_message += buffer[i].ToString("X2");
}
AesParser parser = new AesParser();
byte[] key = parser.ParseKey(PASSWD);
int nK = PASSWD.Length / 8;
int nR = nK + 6;
byte[][] expandedKey = Aes.ExpandKey(key , nK);
byte[,] state = parser.ParseHexString(ByteArrayToHexString(buffer));
byte[][,] all = Aes.InvCipher(state , expandedKey , nR);
byte[,] cardNo = all[nR];
byte[] rst = new byte[4 * 4];
for (int row = 0; row < 4; row++)
{
for (int col = 0; col < 4; col++)
{
rst[(row * 4) + col] = cardNo[row , col];
}
}
return new Tuple<int , string>(status , new String(new ASCIIEncoding().GetChars(rst)));
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("读取卡数据失败!" , sector);
return new Tuple<int , string>(status , string.Empty);
}
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("验证{0}扇区密码失败!" , sector);
return new Tuple<int , string>(status , string.Empty);
}
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("加载密钥失败!");
return new Tuple<int , string>(status , string.Empty);
}
}
private static Tuple<int, string> Mwrf32_Read_Other(int handle, int mode, int sector, int block)
{
int status = Mwrf32.rf_load_key(handle, mode, sector, KEY_Other);
if (status == 0)
{
status = Mwrf32.rf_authentication(handle, 0, sector); //验证密码
if (status == 0)
{
byte[] buffer = new byte[16];
status = Mwrf32.rf_read(handle, sector * 4 + block, buffer); //读数据
if (status == 0)
{
string _message = "";
for (int i = 0; i < 4 * 4; i++)
{
_message += buffer[i].ToString("X2");
}
var array = HexStringToByteArray(_message.ToLower().Substring(0, 16));
string hex = System.Text.Encoding.Default.GetString(array).Replace("\0", " ").Trim();
Console.WriteLine(hex);
string str = decode(hex);
Console.WriteLine(str);
return new Tuple<int, string>(status, str);
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("读取卡数据失败!", sector);
return new Tuple<int, string>(status, string.Empty);
}
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("验证{0}扇区密码失败!", sector);
return new Tuple<int, string>(status, string.Empty);
}
}
else
{
NLog.LogManager.GetCurrentClassLogger().Debug("加载密钥失败!");
return new Tuple<int, string>(status, string.Empty);
}
}
public static string decode(string encryptStr)
{
try
{
//------------解密--------------
// 加密串
encryptStr = encryptStr.Trim();
int length = encryptStr.Length;
string result = "";
for (int i = 1; i <= length; i++)
{
result += chr(ord(encryptStr[i - 1].ToString()) - (length - i - 2) * 2);
}
// 字符反转
char[] arr = result.ToCharArray();
Array.Reverse(arr);
result = new string(arr);
return result;
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
Console.Write(e.StackTrace);
}
return "";
}
private static int ord(string s)
{
return (int)s[0];
}
public static string chr(int i)
{
StringBuilder sbu = new StringBuilder();
sbu.Append((char)i);
return sbu.ToString();
}
private static int Mwrf32_Halt(int handle)
{
return Mwrf32.rf_halt(handle);
}
/// <summary>
///
/// </summary>
/// <param name="handle"></param>
/// <returns></returns>
private static int Mwrf32_Exit(int handle)
{
return Mwrf32.rf_exit(handle);
}
/// <summary>
/// 字节数组转十六进制字符串
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
private static string ByteArrayToHexString(byte[] data)
{
StringBuilder sb = new StringBuilder(data.Length * 3);
foreach (byte b in data)
{
sb.Append(Convert.ToString(b , 16).PadLeft(2 , '0'));
}
return sb.ToString().ToUpper();
}
private static byte[] HexStringToByteArray(string s)
{
s = s.Replace(" " , "");
byte[] buffer = new byte[s.Length / 2];
for (int i = 0; i < s.Length; i += 2)
{
buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i , 2) , 16);
}
return buffer;
}
}
}