随笔20250530 C# 整合 IC卡读写技术解析与实现

news2025/6/5 5:36:32

以下是一个完整、最简化的 FeliCa 读取整合示例(无需 SDK,基于 PCSC NuGet 包),你可以直接运行这个控制台程序,验证能否识别 RC-S300 并读取卡片 UID:


🧪 示例说明

  • 📦 使用 NuGet 包 PCSC

  • 🎯 功能:初始化读卡器,读取插卡的 UID(部分 FeliCa 卡支持)

  • ✅ 仅依赖 Windows 驱动(无需 SDK)


🛠 使用方式

1. 创建控制台项目

dotnet new console -n FelicaReaderExample
cd FelicaReaderExample

2. 安装依赖包

dotnet add package PCSC

 

直接选第一个宝贝!!! 

3. 替换 Program.cs

将下载的 FelicaReaderExample.cs 文件内容,覆盖 Program.cs

或直接复制粘贴内容。

4. 运行程序

插入 FeliCa 卡到 RC-S300,然后运行:

dotnet run

✅ 成功输出示例

找到读卡器:Sony RC-S300
读取成功,卡片 UID: 01-23-45-67-89-AB-CD

FelicaReaderService.cs 

using System;
using System.Linq;
using System.Threading.Tasks;
using PCSC;
using PCSC.Utils;

namespace StarMauiPrinter.Services
{
    /// <summary>
    /// 提供对 FeliCa 卡(如 ICOCA)的读取功能,仅获取 UID(IDm)
    /// </summary>
    public class FelicaReaderService
    {
        /// <summary>
        /// 读取 FeliCa 卡的唯一识别码(IDm / UID)
        /// </summary>
        /// <returns>UID 字符串 或 错误信息</returns>
        public async Task<string?> ReadCardUidAsync()
        {
            try
            {
                // 1. 建立与 PC/SC 子系统的连接上下文
                using var context = ContextFactory.Instance.Establish(SCardScope.System);

                // 2. 获取所有已连接的智能卡读卡器列表
                var readerNames = context.GetReaders();
                if (readerNames == null || readerNames.Length == 0)
                    return "未检测到任何读卡器。";

                var readerName = readerNames[0];

                // 3. 使用第一个读卡器进行连接
                using var reader = new SCardReader(context);
                var result = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);

                if (result != SCardError.Success)
                    return $"连接失败: {SCardHelper.StringifyError(result)}";

                // 4. 构造 APDU 指令读取 UID(IDm)
                // 标准 PC/SC 指令: FF CA 00 00 00
                var command = new byte[] { 0xFF, 0xCA, 0x00, 0x00, 0x00 };
                var receivePci = new SCardPCI();
                var sendPci = SCardPCI.GetPci(reader.ActiveProtocol);
                var receiveBuffer = new byte[256];

                // 5. 发送指令并接收响应
                var transmitResult = reader.Transmit(
                    sendPci,        // 协议控制结构
                    command,        // 发送的指令
                    receivePci,     // 接收的控制结构
                    ref receiveBuffer // 输出缓冲区
                );

                if (transmitResult != SCardError.Success)
                    return $"发送失败: {SCardHelper.StringifyError(transmitResult)}";

                // 6. 解析返回的 UID(通常为 8 字节的 IDm)
                var uid = receiveBuffer.TakeWhile(b => b != 0x00).ToArray();
                if (uid.Length == 0)
                    return "未读取到卡片 UID";

                return $"UID: {BitConverter.ToString(uid)}";
            }
            catch (Exception ex)
            {
                return $"异常: {ex.Message}";
            }
        }
    }
}

 FelicaReaderTest.razor

@page "/felicareadertest"
@inject StarMauiPrinter.Services.FelicaReaderService FelicaReaderService

<h3>ICOCA UID を取得する</h3>

<button class="btn btn-primary" @onclick="ReadUid">取得</button>
<p>@uid</p>


@code {
    private string? uid;

    private async Task ReadUid()
    {
        try
        {
            uid = await FelicaReaderService.ReadCardUidAsync();
        }
        catch (Exception ex)
        {
            uid = $"読み取りに失敗しました: {ex.Message}";
        }
    }
}
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Collections.Generic;
using PCSC;
using PCSC.Utils;

namespace StarMauiPrinter.Services
{
    /// <summary>
    /// Felica读卡器服务类,用于读取ICOCA等Felica格式的IC卡信息
    /// </summary>
    public class FelicaReaderService
    {
        #region 常量定义

        /// <summary>
        /// 获取UID的APDU命令
        /// </summary>
        private static readonly byte[] GET_UID_COMMAND = { 0xFF, 0xCA, 0x00, 0x00, 0x00 };

        /// <summary>
        /// 接收缓冲区大小
        /// </summary>
        private const int RECEIVE_BUFFER_SIZE = 256;

        /// <summary>
        /// 最大重试次数
        /// </summary>
        private const int MAX_RETRY_COUNT = 3;

        /// <summary>
        /// 重试延迟基数(毫秒)
        /// </summary>
        private const int RETRY_DELAY_BASE = 500;

        #endregion

        #region 公共方法

        /// <summary>
        /// 异步读取卡片UID(带重试机制)
        /// </summary>
        /// <returns>返回UID字符串,如果失败则返回错误信息</returns>
        public async Task<string> ReadCardUidAsync()
        {
            return await ExecuteWithRetryAsync(async () =>
            {
                // 方案1:直接创建SCardContext实例
                using var context = new SCardContext();
                context.Establish(SCardScope.System);

                // 获取可用读卡器
                var readerName = GetFirstAvailableReader(context);

                // 连接读卡器并读取UID
                using var reader = new SCardReader(context);
                ConnectToCard(reader, readerName);
                var uid = ReadCardUid(reader);
                return FormatUid(uid);
            });
        }

        /// <summary>
        /// 简化版:异步读取ICOCA卡的详细信息
        /// </summary>
        /// <returns>返回包含UID、余额和基本信息的字符串</returns>
        public async Task<string> ReadIcocaDetailsAsync()
        {
            return await ExecuteWithRetryAsync(async () =>
            {
                using var context = new SCardContext();
                context.Establish(SCardScope.System);

                var readerName = GetFirstAvailableReader(context);
                using var reader = new SCardReader(context);
                ConnectToCard(reader, readerName);

                // 读取基本UID信息
                var uid = ReadCardUid(reader);
                var uidString = FormatUid(uid);

                // 尝试读取余额
                var balance = TryReadBalance(reader);

                // 尝试读取最近一次交易
                var lastTransaction = TryReadLastTransaction(reader);

                return $"ICOCA卡信息:\n" +
                       $"UID: {uidString}\n" +
                       $"余额: {balance}\n" +
                       $"最近交易: {lastTransaction}";
            });
        }

        /// <summary>
        /// 尝试读取余额(修复版)
        /// </summary>
        private string TryReadBalance(SCardReader reader)
        {
            try
            {
                // ICOCA余额读取命令
                var command = new byte[] { 0xFF, 0xCA, 0x00, 0x01, 0x04, 0x8B, 0x00, 0x83, 0x00 };
                var response = new byte[64];

                // 修复:正确使用ref参数
                var result = reader.Transmit(command, ref response);

                // 检查命令是否成功执行
                if (result == SCardError.Success)
                {
                    // 检查响应长度
                    var actualLength = response.Length;
                    if (actualLength >= 4)
                    {
                        // 正确解析余额数据
                        var balance = (response[1] << 8) | response[0];  // Little-endian
                        if (balance > 0 && balance < 50000)
                        {
                            return $"¥{balance}";
                        }

                        // 尝试其他可能的位置
                        for (int i = 0; i < actualLength - 1; i++)
                        {
                            var testBalance = (response[i + 1] << 8) | response[i];
                            if (testBalance > 0 && testBalance < 50000)
                            {
                                return $"¥{testBalance}";
                            }
                        }
                    }
                }
                else
                {
                    return $"命令失败: {result}";
                }
            }
            catch (Exception ex)
            {
                return $"读取失败: {ex.Message}";
            }

            return "无法读取";
        }

        /// <summary>
        /// 尝试读取最近一次交易(修复版)
        /// </summary>
        private string TryReadLastTransaction(SCardReader reader)
        {
            try
            {
                // 交易记录读取命令
                var command = new byte[] { 0xFF, 0xCA, 0x00, 0x02, 0x04, 0x8C, 0x00, 0x80, 0x00 };
                var response = new byte[64];

                // 修复:正确使用ref参数
                var result = reader.Transmit(command, ref response);

                if (result == SCardError.Success && response.Length >= 8)
                {
                    var amount = (response[5] << 8) | response[4];
                    var type = response[0] == 0x05 ? "乘车" : "其他";

                    if (amount > 0 && amount < 10000) // 合理的交易金额范围
                    {
                        return $"{type} ¥{amount}";
                    }
                }
            }
            catch (Exception)
            {
                // 忽略错误
            }

            return "无记录";
        }

        /// <summary>
        /// 检查读卡器状态
        /// </summary>
        /// <returns>返回读卡器状态信息</returns>
        public async Task<string> CheckReaderStatusAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    // 修复:直接创建SCardContext实例
                    using var context = new SCardContext();
                    context.Establish(SCardScope.System);

                    var readerNames = context.GetReaders();
                    if (readerNames.Length == 0)
                        return "状态: 未检测到任何读卡器";

                    var statusInfo = new List<string>();
                    foreach (var readerName in readerNames)
                    {
                        try
                        {
                            // 检查读卡器中是否有卡
                            var cardStatus = CheckCardPresence(context, readerName);
                            statusInfo.Add($"读卡器: {readerName} - 状态: {cardStatus}");
                        }
                        catch (Exception ex)
                        {
                            statusInfo.Add($"读卡器: {readerName} - 状态: 检查失败 ({ex.Message})");
                        }
                    }
                    return string.Join("\n", statusInfo);
                }
                catch (Exception ex)
                {
                    return $"检查状态时发生异常: {ex.Message}";
                }
            });
        }

        /// <summary>
        /// 测试读卡器连接
        /// </summary>
        /// <returns>连接测试结果</returns>
        public async Task<string> TestReaderConnectionAsync()
        {
            return await Task.Run(() =>
            {
                try
                {
                    using var context = ContextFactory.Instance.Establish(SCardScope.System);
                    var readerNames = context.GetReaders();

                    if (readerNames.Length == 0)
                        return "测试失败: 未检测到任何读卡器";

                    var readerName = readerNames[0];
                    using var reader = new SCardReader(context);

                    var result = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);

                    if (result == SCardError.Success)
                    {
                        var protocol = reader.ActiveProtocol;
                        return $"连接测试成功!\n读卡器: {readerName}\n协议: {protocol}";
                    }
                    else
                    {
                        return $"连接测试失败: {SCardHelper.StringifyError(result)}";
                    }
                }
                catch (Exception ex)
                {
                    return $"连接测试异常: {ex.Message}";
                }
            });
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 获取第一个可用的读卡器
        /// </summary>
        /// <param name="context">PC/SC上下文</param>
        /// <returns>读卡器名称</returns>
        /// <exception cref="InvalidOperationException">当没有可用读卡器时抛出</exception>
        private string GetFirstAvailableReader(SCardContext context)
        {
            var readerNames = context.GetReaders();
            if (readerNames.Length == 0)
                throw new InvalidOperationException("未检测到任何读卡器,请确认读卡器已正确连接");

            return readerNames[0];
        }

        /// <summary>
        /// 连接到卡片
        /// </summary>
        /// <param name="reader">读卡器实例</param>
        /// <param name="readerName">读卡器名称</param>
        /// <exception cref="InvalidOperationException">当连接失败时抛出</exception>
        private void ConnectToCard(SCardReader reader, string readerName)
        {
            var result = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
            if (result != SCardError.Success)
            {
                throw new InvalidOperationException(
                    $"连接到读卡器失败: {SCardHelper.StringifyError(result)}。" +
                    "请确认卡片已正确放置在读卡器上");
            }
        }

        /// <summary>
        /// 读取卡片UID
        /// </summary>
        /// <param name="reader">读卡器实例</param>
        /// <returns>UID字节数组</returns>
        /// <exception cref="InvalidOperationException">当读取失败时抛出</exception>
        private byte[] ReadCardUid(SCardReader reader)
        {
            var receivePci = new SCardPCI();
            var sendPci = SCardPCI.GetPci(reader.ActiveProtocol);
            var receiveBuffer = new byte[RECEIVE_BUFFER_SIZE];

            var transmitResult = reader.Transmit(
                sendPci,
                GET_UID_COMMAND,
                receivePci,
                ref receiveBuffer
            );

            if (transmitResult != SCardError.Success)
            {
                throw new InvalidOperationException(
                    $"发送UID读取命令失败: {SCardHelper.StringifyError(transmitResult)}");
            }

            // 提取有效的UID数据(去除填充的0x00)
            var uid = receiveBuffer.TakeWhile(b => b != 0x00).ToArray();

            if (uid.Length == 0 || uid.Length < 4)
            {
                throw new InvalidOperationException("读取到的UID无效或长度不足");
            }

            return uid;
        }

        /// <summary>
        /// 尝试读取额外的卡片信息
        /// </summary>
        /// <param name="reader">读卡器实例</param>
        /// <returns>额外信息字符串</returns>
        private string TryReadAdditionalCardInfo(SCardReader reader)
        {
            try
            {
                // 尝试读取更多信息的示例命令
                var infoCommand = new byte[] { 0xFF, 0xB0, 0x00, 0x00, 0x10 };

                var receivePci = new SCardPCI();
                var sendPci = SCardPCI.GetPci(reader.ActiveProtocol);
                var receiveBuffer = new byte[RECEIVE_BUFFER_SIZE];

                var result = reader.Transmit(
                    sendPci,
                    infoCommand,
                    receivePci,
                    ref receiveBuffer
                );

                if (result == SCardError.Success)
                {
                    var responseData = receiveBuffer.TakeWhile(b => b != 0x00).ToArray();
                    if (responseData.Length > 0)
                    {
                        return $"附加信息: {BitConverter.ToString(responseData)}";
                    }
                }

                return "附加信息: 无法读取或不支持";
            }
            catch (Exception ex)
            {
                return $"附加信息: 读取异常 ({ex.Message})";
            }
        }

        /// <summary>
        /// 检查指定读卡器中是否有卡片
        /// </summary>
        /// <param name="context">PC/SC上下文</param>
        /// <param name="readerName">读卡器名称</param>
        /// <returns>卡片状态描述</returns>
        private string CheckCardPresence(SCardContext context, string readerName)
        {
            try
            {
                using var reader = new SCardReader(context);
                var connectResult = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);

                if (connectResult == SCardError.Success)
                {
                    return "有卡 (已连接)";
                }
                else if (connectResult == SCardError.NoSmartcard)
                {
                    return "无卡";
                }
                else
                {
                    return $"未知状态 ({SCardHelper.StringifyError(connectResult)})";
                }
            }
            catch (Exception)
            {
                return "检查失败";
            }
        }

        /// <summary>
        /// 格式化UID为可读字符串
        /// </summary>
        /// <param name="uid">UID字节数组</param>
        /// <returns>格式化的UID字符串</returns>
        private string FormatUid(byte[] uid)
        {
            if (uid == null || uid.Length == 0)
                return "UID: 无效";

            var uidString = BitConverter.ToString(uid).Replace("-", ":");
            return $"UID: {uidString} (长度: {uid.Length} 字节)";
        }

        /// <summary>
        /// 执行带重试机制的异步操作
        /// </summary>
        /// <param name="operation">要执行的操作</param>
        /// <returns>操作结果</returns>
        private async Task<string> ExecuteWithRetryAsync(Func<Task<string>> operation)
        {
            Exception lastException = null;

            for (int attempt = 1; attempt <= MAX_RETRY_COUNT; attempt++)
            {
                try
                {
                    return await operation();
                }
                catch (Exception ex)
                {
                    lastException = ex;

                    if (attempt == MAX_RETRY_COUNT)
                        break;

                    // 在重试之间添加递增延迟
                    await Task.Delay(RETRY_DELAY_BASE * attempt);
                }
            }

            // 如果所有重试都失败,返回错误信息
            return $"操作失败 (重试 {MAX_RETRY_COUNT} 次): {lastException?.Message ?? "未知错误"}";
        }

        #endregion

        #region 资源清理

        /// <summary>
        /// 清理资源
        /// </summary>
        public void Dispose()
        {
            // 强制垃圾回收,释放未管理资源
            GC.Collect();
        }

        #endregion
    }

    #region 扩展类和数据结构

    /// <summary>
    /// ICOCA卡信息结构
    /// </summary>
    public class IcocaCardInfo
    {
        public string Uid { get; set; } = string.Empty;
        public int Balance { get; set; }
        public DateTime LastUsed { get; set; }
        public List<TransactionRecord> History { get; set; } = new List<TransactionRecord>();
    }

    /// <summary>
    /// 交易记录结构
    /// </summary>
    public class TransactionRecord
    {
        public DateTime Date { get; set; }
        public string Type { get; set; } = string.Empty;
        public int Amount { get; set; }
        public string Station { get; set; } = string.Empty;
    }

    #endregion
}

 


using System;
using System.Linq;
using System.Threading.Tasks;
using PCSC;
using PCSC.Utils;

namespace StarMauiPrinter.Services
{
    public class FelicaReaderService
    {
        /// <summary>
        /// 获取卡的 IDm(UID)、System Code,并根据 IDm 前缀推断卡类型
        /// </summary>
        public async Task<string?> GetCardInfoAsync()
        {
            try
            {
                using var context = ContextFactory.Instance.Establish(SCardScope.System);
                var readers = context.GetReaders();
                if (readers == null || readers.Length == 0)
                    return "未检测到读卡器";

                var readerName = readers[0];
                using var reader = new SCardReader(context);
                var conn = reader.Connect(readerName, SCardShareMode.Shared, SCardProtocol.Any);
                if (conn != SCardError.Success)
                    return $"连接失败: {SCardHelper.StringifyError(conn)}";

                var sendPci = SCardPCI.GetPci(reader.ActiveProtocol);
                var recvPci = new SCardPCI();
                var buffer = new byte[256];

                // 发送 Polling 命令以获取卡信息
                var polling = new byte[] {
                    0xFF, 0x00, 0x00, 0x00, 0x04,
                    0xD4, 0x04, 0x00, 0x01
                };

                var result = reader.Transmit(sendPci, polling, recvPci, ref buffer);
                if (result != SCardError.Success)
                    return $"轮询失败: {SCardHelper.StringifyError(result)}";

                var response = buffer.TakeWhile(b => b != 0x00).ToArray();
                if (response.Length < 18)
                    return "响应数据不足,无法解析卡片信息";

                var idm = response.Skip(9).Take(8).ToArray();
                var idmStr = BitConverter.ToString(idm);
                var idPrefix = $"{idm[0]:X2}-{idm[1]:X2}";

                var systemCode = response.Length >= 27 ? response.Skip(25).Take(2).ToArray() : new byte[] { 0x00, 0x00 };
                var sysCodeStr = $"{systemCode[0]:X2}{systemCode[1]:X2}";

                // 根据 IDm 前缀 和 System Code 判断卡种
                string cardType = sysCodeStr switch
                {
                    "0003" => idPrefix switch
                    {
                        "01-01" or "02-01" => "Suica",
                        "03-01" => "PASMO",
                        "07-01" or "07-02" => "ICOCA",
                        _ => "未知交通卡"
                    },
                    "FE00" or "FE01" => "Edy",
                    "8B01" => "WAON",
                    _ => $"未知卡片(SystemCode: {sysCodeStr}, IDm前缀: {idPrefix})"
                };

                return $"卡类型: {cardType}\nIDm: {idmStr}\nSystem Code: {sysCodeStr}";
            }
            catch (Exception ex)
            {
                return $"异常: {ex.Message}";
            }
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2397296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于爬取的典籍数据重新设计前端界面

1.BooksView(书籍列表页) 2.ClassicsView&#xff08;目录页&#xff09; 3.管理员端

揭秘 NextJS Script 组件

揭秘 NextJS Script 组件 Next.js 的 Script 组件是对原生 <script> 标签的增强封装&#xff0c;主要区别和优势如下&#xff1a; 自动优化加载策略&#xff08;支持按需/延迟加载&#xff09;避免重复加载内置性能优化&#xff08;如预加载、回调钩子&#xff09;简化…

【C++/Linux】TinyWebServer前置知识之IP协议详解

目录 IPv4地址 分类 IP数据报分片 IP 协议在传输数据报时&#xff0c;将数据报分为若干分片&#xff08;小数据报&#xff09;后进行传输&#xff0c;并在目的系统中进行重组&#xff0c;这一过程称为分片&#xff08;Fragmentation&#xff09;。 IP模块工作流程​编辑 I…

Codeforces Round 1028 (Div. 2)(A-D)

题面链接&#xff1a;Dashboard - Codeforces Round 1028 (Div. 2) - Codeforces A. Gellyfish and Tricolor Pansy 思路 要知道骑士如果没了那么这个人就失去了攻击手段&#xff0c;贪心的来说我们只需要攻击血量少的即可&#xff0c;那么取min比较一下即可 代码 void so…

记录一个梦,借助大语言模型图片生成

梦见家门口有一条大河&#xff0c;但大河和其它景物都是灰暗没有鲜艳色彩很普通的梦中场景。大河似乎是长江的支流&#xff0c;但也可能有一个响亮的名字似乎是金沙江。 突然看到一条金红色的龙在快速游动&#xff0c;不敢相信自己的眼睛&#xff0c;因为一直不相信有这种生物…

android binder(二)应用层编程实例

一、binder驱动浅析 从上图看出&#xff0c;binder的通讯主要涉及三个步骤。 在 Binder Server 端定义好服务&#xff0c;然后向 ServiceManager 注册服务在 Binder Client 中向 ServiceManager 获取到服务发起远程调用&#xff0c;调用 Binder Server 中定义好的服务 整个流…

【深度学习】17. 深度生成模型:DCGAN与Wasserstein GAN公式深度推导

深度生成模型:DCGAN与Wasserstein GAN公式深度推导 深度卷积生成对抗网络 DCGAN 在原始 GAN 框架中&#xff0c;生成器和判别器通常使用全连接层构建&#xff0c;这限制了模型处理图像的能力。为此&#xff0c;Radford 等人在 2016 年提出了 DCGAN&#xff08;Deep Convoluti…

设计模式——命令设计模式(行为型)

摘要 本文介绍了命令设计模式&#xff0c;这是一种行为型设计模式&#xff0c;用于将请求封装为对象&#xff0c;实现请求的解耦和灵活控制。它包含命令接口、具体命令、接收者、调用者和客户端等角色&#xff0c;优点是解耦请求发送者与接收者&#xff0c;支持命令的排队、记…

03 APP 自动化-定位元素工具元素定位

文章目录 一、Appium常用元素定位工具1、U IAutomator View Android SDK 自带的定位工具2、Appium Desktop Inspector3、Weditor安装&#xff1a;Weditor工具的使用 4、uiautodev通过定位工具获取app页面元素有哪些属性 二、app 元素定位方法 一、Appium常用元素定位工具 1、U…

PABD 2025:大数据与智慧城市管理的融合之道

会议简介 2025年公共管理与大数据国际会议&#xff08;ICPMBD 2025&#xff09;确实在海口举办。本次会议将围绕公共管理与大数据的深度融合、数据分析在公共管理中的应用、大数据驱动的政策制定与优化等议题展开深入研讨。参会者将有机会聆听前沿学术报告&#xff0c;分享研究…

Golang持续集成与自动化测试和部署

概述 Golang是一门性能优异的静态类型语言&#xff0c;但因其奇快的编译速度&#xff0c;结合DevOps, 使得它也非常适合快速开发和迭代。 本文讲述如何使用Golang, 进行持续集成与自动化测试和部署。主要使用了以下相关技术&#xff1a; dep&#xff1a; 进行包的依赖管理gin…

mysql离线安装教程

1.下载地址: https://downloads.mysql.com/archives/community/ 2.上传安装包到系统目录,并解压 tar -xvf mysql-8.0.34-1.el7.x86_64.rpm-bundle.tar3.检查系统中是否存在mariadb的rpm包 rpm -qa|grep mariadb存在则删除 rpm -e xxx4.解压完后执行如下命令安装 sudo rpm -iv…

基于FPGA的VGA显示文字和动态数字基础例程,进而动态显示数据,类似温湿度等

基于FPGA的VGA显示文字和数字 前言一、VGA显示参数二、字模生成三、代码分析1.vga_char顶层2.vga_ctrl驱动文件3.vga_pic数据准备文件 总结 前言 结合正点原子以及野火的基础例程&#xff0c;理解了VGA本身基本协议&#xff0c;VGA本身显示像素为640*480&#xff0c;因此注意生…

力扣刷题Day 68:搜索插入位置(35)

1.题目描述 2.思路 方法1&#xff1a;回溯的二分查找。 方法2&#xff1a;看到了一个佬很简洁的写法&#xff0c;代码贴在下面了。 3.代码&#xff08;Python3&#xff09; 方法1&#xff1a; class Solution:def searchInsert(self, nums: List[int], target: int) ->…

使用Python绘制节日祝福——以端午节和儿童节为例

端午节 端午节总算是回家了&#xff0c;感觉时间过得真快&#xff0c;马上就毕业了&#xff0c;用Python弄了一个端午节元素的界面&#xff0c;虽然有点不像&#xff0c;祝大家端午安康。端午节粽子&#xff08;python&#xff09;_python画粽子-CSDN博客https://blog.csdn.net…

C#项目07-二维数组的随机创建

实现需求 创建二维数组&#xff0c;数组的列和宽为随机&#xff0c;数组内的数也是随机 知识点 1、Random类 Public Random rd new Random(); int Num_Int rd.Next(1, 100);2、数组上下限。 //定义数组 int[] G_Array new int[1,2,3,4];//一维数组 int[,] G_Array_T …

光伏功率预测 | LSTM多变量单步光伏功率预测(Matlab完整源码和数据)

光伏功率预测 | MATLAB实现基于LSTM长短期记忆神经网络的光伏功率预测 目录 光伏功率预测 | MATLAB实现基于LSTM长短期记忆神经网络的光伏功率预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 光伏功率预测 | LSTM多变量单步光伏功率预测&#xff08;Matlab完整源码和…

一步一步配置 Ubuntu Server 的 NodeJS 服务器详细实录——3. 服务器软件更新,以及常用软件安装

前言 前面&#xff0c;我们已经 安装好了 Ubuntu 服务器系统&#xff0c;并且 配置好了 ssh 免密登录服务器 &#xff0c;现在&#xff0c;我们要来进一步的设置服务器。 那么&#xff0c;本文&#xff0c;就是进行服务器的系统更新&#xff0c;以及常用软件的安装 调整 Ubu…

PyTorch 入门学习笔记

一、简介 PyTorch 是由 Meta&#xff08;原 Facebook&#xff09; 开源的深度学习框架。其前身 Torch 是一个基于 LuaJIT 的科学计算框架&#xff0c;核心功能是提供高效的张量&#xff08;Tensor&#xff09;操作和神经网络支持。由于 Lua 语言的生态限制&#xff0c;Torch 逐…

pycharm生成图片

文章目录 图片例子生成图片并储存&#xff0c;设置中文字体支持两条线绘制散点图和直方图绘制条形图&#xff08;bar&#xff09;绘制条形图&#xff08;横着的&#xff09;&#xff08;plt.barh&#xff09;分组的条形图 颜色和线条风格1. **颜色字符 (color)**其他颜色指定方…