C# 读写FDX-B(ISO11784/85)动物标签源码

本示例使用的发卡器:EM4305 EM4469 ISO11784/85协议125K低频FXD-B动物标签读写发卡器-淘宝网 (taobao.com) 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;  //调用动态库一定要加入这个引用

namespace FDX_B
{
    public partial class Form1 : Form
    {
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //外部函数声明:让设备发出声响
        [DllImport("OUR_IDR.dll", EntryPoint = "idr_beep", CallingConvention = CallingConvention.StdCall)]
        static extern byte idr_beep(UInt32 xms);//xms单位为毫秒 
        //------------------------------------------------------------------------------------------------------------------------------------------------------    
        //读取设备编号,可做为软件加密狗用,也可以根据此编号在公司网站上查询保修期限
        [DllImport("OUR_IDR.dll", EntryPoint = "pcdgetdevicenumber", CallingConvention = CallingConvention.StdCall)]
        static extern byte pcdgetdevicenumber(byte[] devicenumber);//devicenumber用于返回编号 
        //------------------------------------------------------------------------------------------------------------------------------------------------------    
        //EM4205/4305/4469/4569卡读卡
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_read", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_read(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] readdata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡写卡
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_write", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_write(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] writedata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //EM4205/4305/4469/4569卡锁定块
        [DllImport("OUR_IDR.dll", EntryPoint = "em4305_lock", CallingConvention = CallingConvention.StdCall)]
        public static extern byte em4305_lock(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //T5557卡读卡
        [DllImport("OUR_IDR.dll", EntryPoint = "t5557_read", CallingConvention = CallingConvention.StdCall)]
        public static extern byte t5557_read(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] readdata);
        //------------------------------------------------------------------------------------------------------------------------------------------------------
        //T5557卡写卡
        [DllImport("OUR_IDR.dll", EntryPoint = "t5557_write", CallingConvention = CallingConvention.StdCall)]
        public static extern byte t5557_write(byte ctrlword, byte[] seria, byte[] key, byte[] blockflag, byte[] writedata);

        public Form1()
        {
            InitializeComponent();
        }

        private void MessageErrInf(byte Errcode)
        {
            switch (Errcode)
            {
                case 1:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",卡放得远 或 需要密码才能写卡 或 块已锁定!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 2:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",本卡尚未开启密码功能,函数myctrlword中无需加入NEEDKEY", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 3:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",需要密码才能读卡,函数myctrlword要加入NEEDKEY", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 4:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",卡放得远 或 需要密码才能读卡!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 5:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",密码错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 8:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",操作失败,请将卡放在读卡器的感应区!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 12:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",卡放得远 或 密码错误!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 21:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",没有动态库!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 22:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",动态库或驱动程序异常!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 23:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",驱动程序错误或发卡器尚未安装!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 24:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",操作超时,一般是动态库没有反映!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 25:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",发送字数不够!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 28:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",输入错误,可能是启用卡号密码保护而没在页面左上角选择带密码操作!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                default:
                    MessageBox.Show("错误代码:" + Errcode.ToString() + ",未知的错误信息,错误代码:" + Errcode.ToString(), "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
            }
        }

        private ushort GetCrc16Ccitt(byte[] bytes)  //计算crc16ccitt校验码
        {
            ushort crc = 0x0000;
            int i, j;

            for (j = 0; j < bytes.Length; j++)
            {
                crc ^= bytes[j];

                for (i = 0; i < 8; i++)
                {
                    if ((crc & 0x0001) > 0)
                    {
                        crc = (ushort)((crc >> 1) ^ 0x8408);
                    }
                    else { crc = (ushort)(crc >> 1); }
                }
            }
            return crc;
        }
        private ushort checkcrc16citt(byte[] bytes)  // 检测crc16ccitt校验
        {
            ushort crc = 0x0000;
            int i, j;

            for (j = 1; j <= 10; j++)
            {
                crc ^= bytes[j];

                for (i = 0; i < 8; i++)
                {
                    if ((crc & 0x0001) > 0)
                    {
                        crc = (ushort)((crc >> 1) ^ 0x8408);
                    }
                    else { crc = (ushort)(crc >> 1); }
                }
            }
            return crc;
        }

        private Boolean checkgetbitinf(string bitstr, byte[] info) //检测是否有效的FDX-B协议信息
        {
            for (int i = 0; i < 14; i++)
            {
                string thisbit = bitstr.Substring((i + 1) * 9 - 9, 9);
                if (thisbit.Substring(0, 1) == "1")
                {
                    info[13 - i] =(byte) Convert.ToInt16(thisbit.Substring(1, 8),2);
                }
                else { return false; };
            }
            ushort crcitt = checkcrc16citt(info);
            if (crcitt == 0)
            {
                return true;
            }
            else { return false; }            
        }


        private void button1_Click(object sender, EventArgs e)
        {
            byte status;                          //存放返回值
            int j;
            byte myctrlword = 0x00;               //控制字
            byte[] oldpicckey = new byte[4];      //密码
            byte[] mypiccserial = new byte[4];    //卡序列号
            byte[] mypiccdata = new byte[70];     //读卡数据缓冲:卡无线转输分频比、卡内容长度(字节数),及最多返回12个块的数据
            byte[] mypiccblockflag = new byte[2]; //指定读哪一块
            string bitstr;

            textBox1.Text = "0000";
            textBox2.Text = "000000000000";
            textBox3.Text = "00000";
            textBox4.Text = "00000000";
            
            mypiccblockflag[0] = 224;
            mypiccblockflag[1] = 1;

            status = em4305_read(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, mypiccdata);
            if (status == 0)
            {
                idr_beep(30);
                string blockdata = "";
                for (int i = 0; i < mypiccdata[1]; i++)
                {
                    bitstr ="00000000"+ Convert.ToString(mypiccdata[2 + i], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    blockdata =bitstr+ blockdata;
                }
                byte[] info = new byte[14];
                if (checkgetbitinf(blockdata, info))
                {
                    string Serialnumberbit = "";
                    bitstr = "00000000" + Convert.ToString(info[1], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Serialnumberbit = bitstr + Serialnumberbit;
                    bitstr = "00000000" + Convert.ToString(info[2], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Serialnumberbit = bitstr + Serialnumberbit;
                    bitstr = "00000000" + Convert.ToString(info[3], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Serialnumberbit = bitstr + Serialnumberbit;
                    bitstr = "00000000" + Convert.ToString(info[4], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Serialnumberbit = bitstr + Serialnumberbit;
                    bitstr = "00000000" + Convert.ToString(info[5], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    string conutrybit = "";
                    conutrybit = bitstr.Substring(0, 2);
                    bitstr = bitstr.Substring(bitstr.Length - 6);
                    Serialnumberbit = bitstr + Serialnumberbit;
                    Int64 SerialnumberId = Convert.ToInt64(Serialnumberbit, 2);
                    textBox2.Text = SerialnumberId.ToString("D12");

                    bitstr = "00000000" + Convert.ToString(info[6], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    conutrybit = bitstr + conutrybit;
                    Int16 conutryid = Convert.ToInt16(conutrybit, 2);
                    textBox1.Text = conutryid.ToString("D4");
                    
                    bitstr = "00000000" + Convert.ToString(info[7], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    if (bitstr.Substring(7, 1) == "1") { checkBox3.Checked = true; } else { checkBox3.Checked = false; }

                    string Reservedbit = bitstr.Substring(0, 7);
                    
                    bitstr = "00000000" + Convert.ToString(info[8], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);

                    if (bitstr.Substring(0, 1) == "1") { checkBox4.Checked = true; } else { checkBox4.Checked = false; }
                    Reservedbit = bitstr.Substring(1, 7) + Reservedbit;
                    Int16 Reserved = Convert.ToInt16(Reservedbit, 2);
                    textBox3.Text = Reserved.ToString("D5");

                    string Extensionbit = "";
                    bitstr = "00000000" + Convert.ToString(info[11], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Extensionbit = bitstr + Extensionbit;
                    bitstr = "00000000" + Convert.ToString(info[12], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Extensionbit = bitstr + Extensionbit;
                    bitstr = "00000000" + Convert.ToString(info[13], 2);
                    bitstr = bitstr.Substring(bitstr.Length - 8);
                    Extensionbit = bitstr + Extensionbit;
                    Int32 Extension = Convert.ToInt32(Extensionbit, 2);
                    textBox4.Text = Extension.ToString("D8");
                }
                else
                {
                    MessageBox.Show("不是有效的FDX-B协议标签!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            } 
            else { MessageErrInf(status); }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Int16 conutryid = Convert.ToInt16(textBox1.Text.Trim());
            Int64 SerialnumberId = Convert.ToInt64(textBox2.Text.Trim());
            Int16 Reserved = Convert.ToInt16(textBox3.Text.Trim());
            Int32 Extension = Convert.ToInt32(textBox4.Text.Trim());

            if (conutryid > 1023){
                MessageBox.Show("Country国家代码的取值范围是:0~1023!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox1.SelectionStart = 0;
                textBox1.SelectionLength = textBox1.Text.Trim().Length;
                textBox1.Select();
                return;
            }

            if (SerialnumberId > 274877906943)
            {
                MessageBox.Show("SerialNumber序列号的取值范围是:0~274877906943!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox2.SelectionStart = 0;
                textBox2.SelectionLength = textBox2.Text.Trim().Length;
                textBox2.Select();
                return;
            }

            if (Reserved > 16383)
            {
                MessageBox.Show("Reserved保留信息的取值范围是:0~16383!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox3.SelectionStart = 0;
                textBox3.SelectionLength = textBox3.Text.Trim().Length;
                textBox3.Select();
                return;
            }

            if (Extension > 16777215)
            {
                MessageBox.Show("Extension扩展信息的取值范围是:0~16777215!", "示例提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                textBox4.SelectionStart = 0;
                textBox4.SelectionLength = textBox4.Text.Trim().Length;
                textBox4.Select();
                return;
            }

            string Extensionbit = "000000000000000000000000"+Convert.ToString(Extension, 2);
            Extensionbit = Extensionbit.Substring(Extensionbit.Length - 24);

            string Reservedbit = "00000000000000" + Convert.ToString(Reserved, 2);
            Reservedbit = Reservedbit.Substring(Reservedbit.Length - 14);
            if (checkBox4.Checked) { Reservedbit = "1" + Reservedbit; } else { Reservedbit = "0" + Reservedbit; }
            if (checkBox3.Checked) { Reservedbit =  Reservedbit+"1"; } else { Reservedbit =  Reservedbit+"0"; }

            string conutrybit = "0000000000" + Convert.ToString(conutryid, 2);
            conutrybit = conutrybit.Substring(conutrybit.Length - 10);

            string Serialnumberbit = "00000000000000000000000000000000000000" + Convert.ToString(SerialnumberId, 2);
            Serialnumberbit = Serialnumberbit.Substring(Serialnumberbit.Length - 38);

            string fdxbitstr = "10000000000";       //前导码
            fdxbitstr = "1" + Serialnumberbit.Substring(30, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(22, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(14, 8) + fdxbitstr;
            fdxbitstr = "1" + Serialnumberbit.Substring(6, 8) + fdxbitstr;
            fdxbitstr = "1" + conutrybit.Substring(8, 2) + Serialnumberbit.Substring(0, 6) + fdxbitstr;
            fdxbitstr = "1" + conutrybit.Substring(0, 8) + fdxbitstr;
            fdxbitstr = "1" + Reservedbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + Reservedbit.Substring(0, 8) + fdxbitstr;

            byte[] info = new byte[8]; 
            for (int i = 0; i < 8; i++)
            {
                string thisbit = fdxbitstr.Substring((i + 1) * 9 - 9, 9);
                if (thisbit.Substring(0, 1) == "1")
                {
                    info[7 - i] = (byte)Convert.ToInt16(thisbit.Substring(1, 8), 2);
                }
            }
            ushort crc16ccitt = GetCrc16Ccitt(info);
            string crcbit = "0000000000000000" + Convert.ToString(crc16ccitt, 2);
            crcbit = crcbit.Substring(crcbit.Length - 16);
            fdxbitstr = "1" + crcbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + crcbit.Substring(0, 8) + fdxbitstr;

            fdxbitstr = "1" + Extensionbit.Substring(16, 8) + fdxbitstr;
            fdxbitstr = "1" + Extensionbit.Substring(8, 8) + fdxbitstr;
            fdxbitstr = "1" + Extensionbit.Substring(0, 8) + fdxbitstr;

            byte[] writebuf = new byte[16];
            for (int i = 0; i < 16; i++)
            {
                string thisbit = fdxbitstr.Substring((i + 1) * 8 - 8, 8);
                writebuf[15 - i] = (byte)Convert.ToInt16(thisbit, 2);
            }

            byte status;                          //存放返回值
            byte myctrlword = 0x00;               //控制字
            byte[] oldpicckey = new byte[4];      //密码
            byte[] mypiccserial = new byte[4];    //卡序列号
            byte[] mypiccblockflag = new byte[2]; //指定读哪一块

            mypiccblockflag[0] = 224;
            mypiccblockflag[1] = 1;

            status = em4305_write(myctrlword, mypiccserial, oldpicckey, mypiccblockflag, writebuf);
            if (status == 0)
            {
                if (checkBox2.Checked){
                    em4305_lock(myctrlword, mypiccserial, oldpicckey, mypiccblockflag);
                }

                string seriaStr = "";
                for (int i = 0; i < 4; i++)
                {
                    seriaStr = seriaStr + mypiccserial[i].ToString("X2");
                }
                idr_beep(30);
                MessageBox.Show("卡号:" + seriaStr + "写FDX-B协议标签成功!", "提示:", MessageBoxButtons.OK , MessageBoxIcon.Information );
                if (checkBox1.Checked)
                {
                    SerialnumberId = SerialnumberId + 1;
                    textBox2.Text = SerialnumberId.ToString("D12");
                }
            }
            else { MessageErrInf(status); }

        }

        private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
            else { e.Handled = false; }
        }

        private void textBox2_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
            else { e.Handled = false; }
        }

        private void textBox3_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
            else { e.Handled = false; }
        }

        private void textBox4_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!(Char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
            {
                e.Handled = true;
            }
            else { e.Handled = false; }
        }


        private void checkBox2_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox2.Checked)
            {
                if (MessageBox.Show("选择写卡成功后锁定保护将不能再次更改标签信息,确定要启动保护功能吗!", "提示:", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
                {
                    checkBox2.Checked = false;
                }
            }
        }

        private void button3_Click(object sender, EventArgs e)
        {
            byte status = idr_beep(50);
            if(status!=0){
                MessageErrInf(status);
            }
        }
    }
}

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

API 设计:使用 Node.js 和 Express.js 的综合教程

API&#xff08;应用程序编程接口&#xff09;设计涉及创建一个高效而强大的接口&#xff0c;允许不同的软件应用程序相互交互。 说明 本教程将指导您使用 Node.js 和 Express.js 作为核心技术来规划、设计和构建 API。但是&#xff0c;这些原则可以应用于任何语言或框架。我们…

APP软件外包开发需要注意的问题

在进行APP软件开发时&#xff0c;有一些关键问题需要特别注意&#xff0c;以确保项目的成功和用户满意度。以下是一些需要注意的问题&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合作。 清晰的需求定义&a…

详解STUN与TR111

STUN协议定义了三类测试过程来检测NAT类型&#xff1a; Test1&#xff1a;STUN Client通过端口{IP-C1:Port-C1}向STUN Server{IP-S1:Port-S1}发送一个Binding Request&#xff08;没有设置任何属性&#xff09;。STUN Server收到该请求后&#xff0c;通过端口{IP-S1:Port-S1}把…

统计二叉树中的伪回文路径 : 用位运用来加速??

题目描述 这是 LeetCode 上的 「1457. 二叉树中的伪回文路径」 &#xff0c;难度为 「中等」。 Tag : 「DFS」、「位运算」 给你一棵二叉树&#xff0c;每个节点的值为 1 到 9 。 我们称二叉树中的一条路径是 「伪回文」的&#xff0c;当它满足&#xff1a;路径经过的所有节点值…

一个正整数转为2进制和8进制,1的个数相同的第23个数是什么?

package cn.com;import java.lang.*;//默认加载public class C2 {//10进制转8进制static int HtoO(int n){int cnt 0;while(n!0){cntn%8;n/8;}return cnt;}//10进制转2进制static int HtoB(int n){int cnt 0;while(n!0){cntn%2;n/2;}return cnt;}public static void main(Str…

Windows服务设置多个服务依赖项避免服务启动失败找不到数据库

添加多个服务依赖项建议通过命令行的方式添加&#xff1a; winr键打开命令行 cmd 命令行添加命令如下&#xff1a; sc config "thinvent-auth" depend "MySQL57"/"RabbitMQ"/"Redis" sc config "服务A" depend "服务…

C#,《小白学程序》第十四课:随机数(Random)第一,几种随机数的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十四课&#xff1a;随机数&#xff08;Random&#xff09;第一&#xff0c;几种随机数的计算方法与代码 /// 本课初步接触一下随机数。 /// </summary> /// <param name"sender"></param> ///…

LiveVIS视图库1400-如何切换数据库?默认使用的数据库是什么?如何切换到Mysql/MariaDB?

LiveVIS视图库1400-如何切换数据库&#xff1f;默认使用的数据库是什么&#xff1f;如何切换到Mysql/MariaDB? 1、切换成Mysql/Mariadb数据库1.1 连接数据库1.2 创建数据库实例1.3 配置.ini文件1.4 重启完成切换 1、切换成Mysql/Mariadb数据库 LiveVIS 默认使用 sqlite3 文件…

重新开启GPT Plus充值通道——基于前端开发者工具

chatGPT PLUS充值通道的关闭 由于chatGPT用户激增&#xff0c;近日&#xff0c;OpenAI的CEO Sam Altman宣布需要暂停新用户对ChatGPT Plus的订阅。在X上&#xff0c;他表达了对于确保用户体验的承诺&#xff0c;同时也提到了用户可以通过应用程序内的通知功能来了解服务恢复的…

笔记本电脑可以投屏到电视吗?Win、Mac、Linux分别怎么投屏?

如果你的电视是安卓电视&#xff0c;那么答案是&#xff1a;完全可以&#xff01; 不管你的笔记本电脑是Windows系统、macOS系统还是Linux系统&#xff0c;你都可以借助AirDroid Cast的电脑客户端或网页版&#xff0c;将电脑屏幕投屏到安卓智能电视上。 首先&#xff0c;你需要…

Unity技美35——再URP管线环境下,配置post后期效果插件(post processing)

前两年在我的unity文章第10篇写过&#xff0c;后效滤镜的使用&#xff0c;那时候大部分项目用的还是unity的基础管线&#xff0c;stander管线。 但是现在随着unity的发展&#xff0c;大部分项目都用了URO管线&#xff0c;甚至很多PC端用的都是高效果的HDRP管线&#xff0c;这就…

网络数据结构skb_buff原理

skb_buff基本原理 内核中sk_buff结构体在各层协议之间传输不是用拷贝sk_buff结构体&#xff0c;而是通过增加协议头和移动指针来操作的。如果是从L4传输到L2&#xff0c;则是通过往sk_buff结构体中增加该层协议头来操作&#xff1b;如果是从L4到L2&#xff0c;则是通过移动sk_…

井盖位移传感器怎么监测井盖安全

井盖在城市基础设施建设中扮演着不可或缺的角色&#xff0c;虽然看似并不起眼但确实是城市规划中一个重要的组成部分。在城市规划建设之初都需要首先考虑排水系统的设计&#xff0c;而井盖作为排水系统的一个重要组成部分&#xff0c;一旦出现问题便会造成交通中断或者环境受影…

【洛谷 P1636】Einstein学画画 题解(图论+欧拉通路)

Einstein学画画 题目描述 Einstein 学起了画画。 此人比较懒~~&#xff0c;他希望用最少的笔画画出一张画…… 给定一个无向图&#xff0c;包含 n n n 个顶点&#xff08;编号 1 ∼ n 1 \sim n 1∼n&#xff09;&#xff0c; m m m 条边&#xff0c;求最少用多少笔可以画…

C#,《小白学程序》第十七课:随机数(Random)第四,移动平均值(Moving Average)的计算方法与代码

1 文本格式 /// <summary> /// 《小白学程序》第十七课&#xff1a;随机数&#xff08;Random&#xff09;第四&#xff0c;移动平均值的计算方法与代码 /// 继续学习数据统计&#xff0c;移动平均值的计算方法 /// 移动平均值就是一定步长内数值的平均值&#xff0c;用…

C#,《小白学程序》第十六课:随机数(Random)第三,正态分布的随机数的计算方法与代码

1 随机数的问题 用 C# Random 类生成的随机数是平均分布的。也就是各数据段的出现的次数差不多。彩票号码属于这种随机数。 而很多很多常见的随机数&#xff0c;比如&#xff1a;成绩&#xff0c;却是符合正态分布的。 因而很多时候需要生成符合正态分布规律的随机数。 2 文…

20年的大厂技术总监给云原生从业者的建议

云原生是一种构建和运行应用程序的方法&#xff0c;是一套技术体系和方法论。云原生的英文可拆解为Cloud和Native。Cloud表示应用程序位于云中&#xff0c;而不是传统的数据中心&#xff1b;Native表示应用程序设计之初就被考虑部署到云的环境&#xff0c;为云而生&#xff0c;…

micro_ros需要用到的hardware

我没有那么长的线啊&#xff0c;所以就用一个4块5的usb转串口看看 没有那么高档的开发板&#xff0c;就用主流的STM32F103C8T6试试看 这应该就是个仿真器了&#xff0c;一个字不认得都能够看的出来吧

集「才华」与「美貌」于一身的原型设计利器—摹客RP

文章目录 画原型做设计&#xff0c;用摹客RP就够了 初遇摹客再遇摹客RP摹客RP简介与注册摹客RP的突出亮点1️⃣拥有海量矢量图标&#xff0c;满足各种设计场景2️⃣打造高扩展性组件&#xff0c;打破传统组件编辑模式3️⃣海量摹客RP模板例子随意挑选4️⃣实现多人实时协同&…

【ArcGIS Pro微课1000例】0035:栅格影像拼接(dem高程数据)

本实验讲解在ArcGIS Pro中,栅格数据的两种拼接(镶嵌)方法,适用于遥感影像、DOM、DEM、DSM等常见栅格数据。 文章目录 一、加载实验数据二、栅格拼接工具1. 镶嵌2. 镶嵌至新栅格三、注意事项四、拓展阅读一、加载实验数据 加载配套实验数据中的0035.rar中的两个dem数据,如…