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#

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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;
}
}
}