自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

跨链技术践行者

爱好生活和大自然,向往无头绪的研究

  • 博客(1)
  • 资源 (146)
  • 论坛 (2)
  • 收藏
  • 关注

转载 V8VM架构与设计

VM 我们认为一个良好的虚拟机实现必须在做到架构设计优雅的同时满足易用性和安全性的需求,在经过对比参考EVM、EOS、C Lua、V8等相关虚拟机的优缺点之后,我们从根源上解决了很多EVM和EOS不合理性设计与问题,并且基于V8在NodeJs和Chrome上的优异表现,最终构建了基于V8的IOST虚拟机。 1. IOST V8VM架构与设计 V8VM架构的核心是VMManger,主要有如下三个功能: VM入口,对外接收其他模块的请求,包括RPC请求、Block验证、Tx验证等等,预处理、.

2020-09-22 10:21:10 211 1

ImageButton,WINCE,自定义用户控件的实现,C#

ImageButton,WINCE,自定义图片按钮控件的实现,C#,可以在wince环境里调试

2013-01-02

工业互联网平台 安全白皮书(2020)

工业互联网平台 安全白皮书(2020)

2020-12-24

工业区块链应用指南,工业互联网

工业区块链应用指南,工业互联网

2020-12-24

C#_string_byte数组转换解析

C# string byte数组转换解析 C# string byte数组转换实现的过程是什么呢?C# string byte数组间的转换需要注意什么呢?C# string byte数组间转换所涉及的方法是什么呢?让我们来看看具体的内容: C# string byte数组转换之string类型转成byte[]: byte[] byteArray = System.Text.Encoding.Default.GetBytes ( str ); 反过来,byte[]转成string: string str = System.Text.Encoding.Default.GetString ( byteArray ); 其它编码方式的,如System.Text.UTF8Encoding,System.Text.UnicodeEncoding class等;例如: string类型转成ASCII byte[]:("01" 转成 byte[] = new byte[]{ 0x30, 0x31}) 1 byte[] byteArray = System.Text.Encoding.ASCII.GetBytes ( str ); ASCII byte[] 转成string:(byte[] = new byte[]{ 0x30, 0x31} 转成 "01") 2 string str = System.Text.Encoding.ASCII.GetString ( byteArray ); 有时候还有这样一些需求: byte[] 转成原16进制格式的string,例如0xae00cf, 转换成 "ae00cf";new byte[]{ 0x30, 0x31}转成"3031":

2013-12-20

基于libusbdotnet开发的USB源码

程序是在libusbdotnet的基础上编写的简易的usb助手软件。软件只是初版,可实现正常的收发usb数据(D12测试通过),这是把所有的东西中分离出来的一个助手案例,读者可以根据此版本来自由扩展,使基于libusbdotnet的usb助手更加完善。反正不要积分你们自己给个好评呗!

2013-12-19

北航2011年硕士研究生入学考试数据结构与C语言试题与答案

2011 年硕士研究生入学考试 “数据结构与C语言程序设计”(科目代码:991)试题与答案 一、单项选择题(本题共20分,每小题各2分) 1.下列关于线性表的存储结构的叙述中,错误的是。 A.线性表的顺序存储结构中隐式地存储了数据元素之间的逻辑关系 B.线性表的顺序存储结构一定需要占用一片地址连续的存储空间 C.线性表的链式存储结构通过指针来反映数据元素之间的逻辑关系 D.线性表的链式存储结构占用的存储空间一定不连续 2.若front 和rear 分别表示链接队列的队头指针与队尾指针,则向队列中插入一个由p 指的新元素的过程是依次执行。 A.rear=p; front=p; B.front=p

2013-01-02

区块链学习资料.zip

塔里实验室大学(TLU)。我们的使命是要平衡和可访问的首选目的地区块链的学习材料,数字货币和数字资产学习材料。      我们希望使这一次学习的经历对我们TLU:来增长我们的知识基础和内部专业知识或进修。我们认为这也将是一个很好的资源所需的众多学科感兴趣的人了解区块链技术。       我们希望这个平台是一个学习的地方,任何人都能使用,无论他们的专业程度。我们的目标是覆盖相关的一系列广泛的话题TLU空间,从一个初学者水平和延伸的道路更深层次的复杂性。       欢迎您为我们的网上内容。来帮助你开始,我们编译的样式指南TLU报告。使用这种风格指南,您可以帮助我们确保一致性在TLU报告的内容和布局。

2019-09-16

Permissioned Blockchain-Based Security for SDN in IoT Cloud Networks

Permissioned Blockchain-Based Security for SDN in IoT Cloud Networks,Abstract—The advancement in cloud networks has enabled connectivity of both traditional networked elements and new devices from all walks of life, thereby forming the Internet of Things (IoT). In an IoT setting, improving and scali

2020-12-05

Cocos2D-X游戏开发技术精解

作者介绍刘剑卓 有点文艺的IT男,会做美食的运动男,喜欢电影的80后。拥有八年的游 戏开发经验,精通移动平台以及PC平台游戏的开发,在过往的职业生涯已有 多款上线畅销游戏。拥有自主研发开发工具、引擎以及游戏产品的能力,有应 用第三方先进引擎的开发经验,熟练使用多种编程语言、脚本语言以及3D渲 染技术。热衷于国内外游戏行业状况和国际技术潮流,关注移动互联网以及游 戏领域的发展。 2作品目录目 录 第1章 Cocos2D-X引擎的介绍 1 1.1 何为游戏引擎 1 1.1.1 游戏的核心—引擎 1 1.1.2 引擎的特点 2 1.1.3 知名的引擎介绍 4 1.1.4 引擎的分类 5 1.2 Cocos2D-X引擎的来历 8 1.3 引擎的版本 9 1.4 下载与安装 10 1.5 引擎的组成 13 1.6 技术文档 15 1.7 成功的游戏 17 1.8 Cocos2D-X引擎的体系 18 1.9 Cocos2D-X引擎的版权声明 19 1.10 本章小结 20 第2章 Cocos2D-X引擎的 开发环境 21 2.1 跨平台的开发 21 2.2 建立开发环境 23 2.2.1 PC开发环境 23 2.2.2 Android开发环境 26 2.2.3 iOS开发环境 35 2.3 引擎中的混合编译 38 2.3.1 Java与C++的混合编译 38 2.3.2 Objective-C与C++的混合编译 41 2.4 引擎的启点 42 2.4.1 应用程序入口 43 2.4.2 引擎应用入口 44 2.5 丰富的示例程序 46 2.5.1 TestCpp示例项目 46 2.5.2 脚本示例项目 47 2.5.3 MoonWarriors示例项目 47 2.6 本章小结 48 第3章 引擎的核心——渲染框架 49 3.1 基本框架 50 3.1.1 引擎的位置 50 3.1.2 根源种子 51 3.1.3 子类结构 57 3.2 渲染框架 57 3.2.1 框架结构 58 3.2.2 摄像机类(CCCamera) 59 3.2.3 导演类(CCDirector) 59 3.2.4 场景类(CCScene) 62 3.2.5 图层类(CCLayer) 64 3.2.6 精灵类(CCSprite) 68 3.2.7 精灵集合类(CCSpriteBatchNode) 72 3.2.8 精灵帧缓冲(CCSpriteFrameCache) 74 3.2.9 Zwoptex纹理编辑器 76 3.3 文字与字体 80 3.3.1 TTF类型标签(CCLabelTTF) 81 3.3.2 BMFont标签类(CCLabelBMFont) 84 3.3.3 Atlas标签类(CCLabelAtlas) 87 3.4 菜单按钮 89 3.5 几何绘制DrawPrimitives 94 3.6 CocosBuilder编辑器 95 3.6.1 CocosBuilder使用指南 95 3.6.2 引擎中的应用 97 3.7 本章小结 98 第4章 动作功能 100 4.1 概述 100 4.2 动作基类 101 4.2.1 动作类的继承关系 102 4.2.2 动作基类CCAction的成员函数 102 4.2.3 类CCNode中与动作有关的函数 104 4.3 时间动作 105 4.3.1 及时动作 105 4.3.2 持续动作 109 4.4 组合动作类 116 4.4.1 序列动作类(CCSequence) 116 4.4.2 同步动作类(CCSpawn) 118 4.4.3 重复动作类(CCRepeat & CCRepeatForever) 119 4.5 可变速度类(CCEaseAction) 120 4.5.1 CCEaseIn、CCEaseOut和CCEaseInOut 122 4.5.2 EaseSineIn、EaseSineOut和EaseSineInOut 124 4.5.3 CCEaseBackIn、CCEaseBackOut和CCEaseBackInOut 124 4.5.4 EaseExponentialIn、EaseExponentialOut和EaseExponentialInOut 125 4.5.5 CCEaseBounceIn、CCBounceOut和CCBounceInOut 125 4.5.6 CCEaseElasticIn、CCEaseElasticOut和CCEaseElasticInOut 125 4.6 速度类(CCSpeed) 125 4.7 延迟动作类(CCDelay) 127 4.8 跟随动作类(CCFollow) 128 4.9 扩展动作类 129 4.9.1 概述 129 4.9.2 翻页动作(CCPageTurn3D) 130 4.9.3 波纹动作(CCWaves3D) 130 4.9.4 格子动作类(CCGridAction) 131 4.10 动画动作类 132 4.10.1 精灵帧 133 4.10.2 精灵帧缓冲 134 4.10.3 动画类 135 4.10.4 动画动作 136 4.11 动画编辑器 136 4.11.1 概述 136 4.11.2 CocosBuilder编辑器中的精灵动画 137 4.11.3 SpriteX草莓编辑器 138 4.11.4 MotionWelder动画编辑器 139 4.12 样例程序 141 4.13 本章小结 143 第5章 用户交互 147 5.1 概述 147 5.2 玩家交互信息 149 5.3 触摸操作的处理机制 149 5.4 接收操作 153 5.5 分发机制 154 5.6 处理响应 157 5.7 多点触碰 159 5.8 加速计的响应函数 161 5.9 本章小结 162 第6章 游戏背景 164 6.1 概述 164 6.2 2D游戏背景的类型 164 6.3 砖块地图编辑器 166 6.3.1 地图编辑器概述 167 6.3.2 Tile Map Editor(砖块地图编辑器) 168 6.3.3 制作一张游戏地图 170 6.3.4 编辑器中的属性功能 172 6.4 砖块地图Tile Map 173 6.5 地图数据的格式 175 6.5.1 编辑器导出的文件 175 6.5.2 地图文件分析 176 6.6 砖块地图的实现 178 6.6.1 砖块地图类CCTMXTiledMap 179 6.6.2 地图图层类CCTMXLayer 181 6.6.3 地图物体层CCTMXObjectGroup 183 6.7 示例项目 184 6.8 背景的滚动与角色移动 186 6.9 多层背景滚动效果 188 6.10 本章小结 190 第7章 物理模拟与碰撞检测 192 7.1 概述 192 7.2 游戏中的碰撞检测 193 7.3 碰撞检测的方法 194 7.3.1 平面几何在碰撞检测中的应用 194 7.3.2 物体的包围盒 197 7.3.3 AABB碰撞检测技术 198 7.4 基本物理知识 199 7.5 你好!Box2D! 201 7.5.1 概述 201 7.5.2 物理世界 202 7.5.3 游戏中的两个世界 202 7.6 Box2D的基础知识 203 7.6.1 概述 204 7.6.2 概念定义 204 7.6.3 物理引擎的模块 205 7.7 引 擎 内 核 205 7.7.1 基本配置 206 7.7.2 内存管理机制 207 7.7.3 工厂模式 208 7.7.4 数据单位 208 7.7.5 用户数据 209 7.8 物理世界World 210 7.8.1 创建和摧毁一个世界 210 7.8.2 让世界运转起来 211 7.8.3 探索世界 212 7.8.5 AABB查询 213 7.8.6 光线投射(Ray Casts) 214 7.9 形状Shapes 216 7.9.1 碰撞模块 216 7.9.2 形状Shape的作用 216 7.9.3 圆形(Circle Shapes) 216 7.9.4 多边形(b2PolygonShape) 217 7.10 框架Fixtures 218 7.10.1 动态模块(Dynamics Module) 219 7.10.2 框架(Fixtures) 219 7.10.3 密度(Density) 219 7.10.4 摩擦(Friction) 220 7.10.5 恢复(Restitution) 220 7.10.6 筛选(Filtering) 220 7.10.7 感应器(Sensors) 221 7.11 物体Bodies 222 7.11.1 物体定义 222 7.11.2 位置和角度(Position and Angle) 223 7.11.3 阻尼(Damping) 223 7.11.4 休眠参数(Sleep Parameters) 224 7.11.5 固定旋转(Fixed Rotation) 224 7.11.6 子弹(Bullets) 224 7.11.7 活动状态(Activation) 225 7.11.8 用户数据(User Data) 226 7.12 关节(Joints) 226 7.12.1 关节的定义(JointDef) 226 7.12.2 关节的属性 227 7.12.3 距离关节(Distance Joint) 228 7.12.4 旋转关节(Revolute Joint) 229 7.12.5 移动关节(Prismatic Joint) 230 7.12.6 滑轮关节(Pulley Joint) 231 7.12.7 齿轮关节(Gear Joint) 232 7.12.8 鼠标关节(Mouse Joint) 234 7.12.9 线性关节(Line Joint) 235 7.12.10 焊接关节(Weld Joint) 235 7.13 接触(Contants) 235 7.13.1 概述 236 7.13.2 接触类(Contact Class) 237 7.13.3 访问接触(Accessing Contacts) 237 7.13.4 接触监听器(Contact Listener) 238 7.13.5 接触筛选(Contact Filtering) 240 7.14 示例项目 241 7.14.1 Box2dTest示例项目 241 7.14.2 调试绘图DebugDraw 243 7.14.3 创建精灵刚体 244 7.15 本章小结 246 第8章 游戏中的声音 249 8.1 概述 249 8.2 音乐与音效 250 8.3 声音格式 250 8.4 CocosDenshion声音模块 252 8.5 背景音乐操作函数 253 8.6 声音音效操作函数 255 8.7 示例程序 256 8.8 本章小结 259 第9章 文件操作模块 261 9.1 概述 261 9.2 引擎文件操作模块 261 9.3 读取文件 263 9.4 写入文件 267 9.5 游戏中用户数据 269 9.5.1 游戏中的用户数据 269 9.5.2 用户数据的基本类型 270 9.5.3 读取与写入操作 271 9.6 示例程序 272 9.7 本章小结 274 第10章 内存管理机制 277 10.1 内存管理概述 277 10.2 引用计数 278 10.3 自动释放池 280 10.3.1 使用方法 280 10.3.2 实现原理 281 10.4 管 理 模 式 284 10.4.1 引擎当中的应用 284 10.4.2 缓冲区 285 10.5 日志调试方式 286 10.6 本章小结 288 第11章 粒子系统 290 11.1 概述 290 11.2 粒子效果 291 11.3 粒子系统的来历 292 11.4 引擎当中的粒子系统 293 11.5 粒子的生命周期 294 11.6 粒子的属性 295 11.7 粒子发射器属性 296 11.7.1 发射器共有的属性 296 11.7.2 重力发射器模式(Gravity) 304 11.7.3 半径发射器模式(Radius) 306 11.8 粒子效果编辑器 307 11.8.1 概述 308 11.8.2 Particle Designer的使用方法 308 11.8.3 引擎中应用 310 11.9 本章小结 312 第12章 Lua脚本语言 314 12.1 概述 314 12.2 Lua脚本语言简介 315 12.3 为什么需要它? 316 12.3.1 简易性 316 12.3.2 可扩展性 316 12.3.3 高效性 317 12.3.4 可移植性 317 12.4 Lua脚本语言的语法 318 12.4.1 类型与数值 318 12.4.2 表达式 320 12.4.3 语句 322 12.4.4 函数 326 12.5 Lua在引擎中的应用 328 12.5.1 Lua与C/C++ 328 12.5.2 引擎中的脚本引擎 329 12.6 样例程序 331 12.6.1 脚本引擎初始化 332 12.6.2 游戏内容的实现脚本 333 12.6.3 农场层的实现 334 12.6.4 菜单层的实现 337 12.7 本章小结 338 第13章 Cocos2D-HTML5引擎版本 340 13.1 概述 340 13.2 HTML的发展史 341 13.2.1 HTML版本 341 13.2.2 XHTML版本 342 13.2.3 HTML5是未来之星 342 13.3 HTML5新特性 342 13.3.1 跨平台的特性 343 13.3.2 Canvas API 343 13.3.3 WebGL 344 13.3.4 其他特性 345 13.4 JavaScript语言基础 346 13.4.1 概述 346 13.4.2 变量 347 13.4.3 数据类型 348 13.4.4 运算符 348 13.4.5 语句 351 13.4.6 对象 352 13.4.7 函数 353 13.4.8 事件 354 13.5 Cocos2d-HTML5引擎 356 13.5.1 HTML5版本介绍 356 13.5.2 安装引擎 357 13.5.3 示例程序 357 13.5.4 引擎的架构 360 13.6 JS Binding技术的实现 362 13.6.1 概述 362 13.6.2 SpiderMonkey 362 13.6.3 示例程序 363 13.7 本章小结 364 第14章 引擎之外的附加功能 366 14.1 概述 366 14.2 网络通讯支持 367 14.2.1 HTTP介绍 367 14.2.2 curl库(libcurl) 368 14.2.3 HTTP在引擎中的应用 368 14.2.4 HTTP示例项目 372 14.2.5 Socket的介绍 376 14.2.6 BSD Socket在引擎中的应用 378 14.3 收费模式 379 14.3.1 下载计费 379 14.3.2 内置计费 380 14.3.3 广告版本 380 14.4 社交网络在游戏中的应用 381 14.4.1 Game Center 382 14.4.2 OpenFeint 384 14.5 数据分析 385 14.5.1 Flurry介绍 386 14.5.2 友盟 390 第15章 Cocos2D-X引擎的未来 391 15.1 概述 391 15.2 Cocos2D引擎的走势 391 15.3 Cocos2D-X引擎的不足 392 15.3.1 丰富的UI 393 15.3.2 完善的工具 393 15.3.3 支持网络通迅 395 15.3.4 版本的统一 395 15.3.5 数据安全 396 15.4 Cocos2D-X引擎增强的功能 396 15.4.1 良好的中文支持 397 15.4.2 游戏基本框架 397 15.4.3 游戏逻辑支持 398 15.4.4 脚本化编程 399 15.4.5 可视化的操作界面 400 15.5 会不会有Cocos3D? 401 15.6 本章小结 403

2014-01-04

20190425103902457.pdf

在供应链保理业务模式概述的基础上,本文从对象—信息—功能三个维度展开了对区块链技术与供 应链保理业务的耦合分析,并从供应商保理融资放款、核心企业到期付款和债权凭证的确认分割转让三方 面提出了智能合约在供应链保理业务中的具体应用场景,同时提出以区块链智能合约技术为支撑的供应链 保理业务流程基本框架,对基于区块链的供应链智能保理业务这一全新模式的具体实施过程作了详尽阐述, 并将两种模式进行对比分析,强调了区块链技术对于业务客体流程的重要作用。接着重点利用博弈论思想, 从供应链业务主体决策角度出发,对考虑区块链影响的供应链保理融资过程进行三方博弈分析,以效用最 大化为原则求得均衡解(放贷,还款,还款),揭示区块链技术对于主体方决策行为的优化作用。

2020-06-22

用区块链技术保障物联网安全

物联网安全威胁真正引起了人们的关注,但是,保障物联网设备的安全具有极 度的挑战性,各设备之间的通信互信是物联网安全的基石,由于大多IoT设备成本 很低算力不足,传统的安全技术在物联网设备上过重而很难实施,区块链技术有 着先天的分布式可信模式,采用轻量级区块链技术保障物联网设备的可信与安全 成为云安全联盟的独特研究思路。本白皮书是物联网与区块链结合的投石问路之 作,CSA全球与大中华区的专家们给广大读者又一专业奉献。

2020-12-05

自定义图片按钮控件

C#实现 WINCE 用户控件的应用和实现

2013-01-20

读取GPS的串口程序(C#)

该代码是基于WINCE 6.0SDK专业版的SDK开发的程序能读取GPS的串口数据,平台是VS2008,用C#写的,最好装WINCE6.0的SDK专业版才能运行,程序可供自学读GPS串口使用。

2013-04-17

Win32动画制作

一个关于win32开发图片移动的动画,可以自由的控制,对初学者是一个不错的选择。

2013-03-10

基于C++开发的射击游戏

用DDraw实现射击游戏说明文档 要点一:画图自动切割 IDirectDrawSurface7::BltFast()方法中没有自动切割功能,即当画图元素超出窗口以外时不会自动切割,DDraw选择自动忽略不画,造成一旦超出窗口,画图元素会突然消失。 解决这一问题的方法是手动切割,代码如下: //自动切割 RECT scRect; //存放当前窗口大小区域 ZeroMemory( &scRect, sizeof( scRect ) ); GetWindowRect( GetActiveWindow(), &scRect ); //防止图片左上角超过窗口左上角 if ( x < 0 ) { m_rect.left -= x; x = 0; } if ( y < 0 ) { m_rect.top -= y; y = 0; } //防止图片右下角超过窗口右下角 x = x > scRect.right ? scRect.right : x; y = y > scRect.bottom ? scRect.bottom : y; m_rect.right = x + m_rect.right - m_rect.left > scRect.right ? scRect.right - x + m_rect.left : m_rect.right; m_rect.bottom = y + m_rect.bottom - m_rect.top > scRect.bottom ? scRect.bottom - y + m_rect.top : m_rect.bottom; 只需将上述代码加在CGraphic::BltBBuffer() 中的m_bRect = m_rect; 前即可。 要点二:背景的滚轴实现 画背景可以分为以下三种情况: 情况一:背景图片与窗口等高 情况二:背景图片高度小于窗口高度 情况三:背景图片高度大于窗口高度 上述讲解图与代码相对应地看,有助于容易理解。 另外,要点一实现之后,由于已经可以自动切割,画背景可以用其它方法。 要点三:精灵图的实现 在游戏中,如RPG游戏中的人物图、射击类游戏的飞机、爆炸等,叫做精灵图。 精灵图实际上是将所有帧的图片放在一个文件中,游戏时靠一个RECT来控制画图像文件中的哪一部分,进而控制游戏显示哪一帧图,只需控制好RECT的位置即可。如下图: 控制RECT的四个角的坐标的移动,有以下代码: if (m_timeEnd – m_timeStart > 100) //只有到了100ms之后才绘图 { m_ImageID++; if(m_ImageID - m_beginID >= num) { m_ImageID = m_beginID; //最后一帧的下一帧是第一帧 } m_timeStart = timeGetTime(); } int id = m_ImageID++; SetRect(&m_rect, 41 * id, 0, 41 * (id + 1), 41); //飞机精灵图大小是41×41 m_pGraph->BltBBuffer(m_pImageBuffer, true, m_Pos.x, m_Pos.y, m_rect); 这样就实现了精灵动画的效果。 要点四:拿STL进行子弹的实现 子弹的实现可以使用STL中的vector,当按下开火键时发出一颗子弹,就往vector中添加一个结点;当子弹飞出窗口或击中敌机时,再将结点从vector中删除。每帧游戏画面中子弹飞行时只需将vector中的所有子弹进行处理、绘画即可。 参考代码如下: 1.添加子弹 if (g_ctrlDown) //当ctrl键按下时开炮! { m_BulletEnd = m_Gtime->GetTime(); if ((m_BulletEnd - m_BulletStart) * 1000 > 120) //如果连续按着开火键不放,这里控制不会发出太多子弹 { m_BulletStart = m_BulletEnd; MBULLET tmpBullet; tmpBullet.pos.x = m_SPos.x - 1; //记录开火时的子弹位置 tmpBullet.pos.y = m_SPos.y - 26; tmpBullet.speed = 5; //该子弹的飞行速度 m_BulletList.push_back(tmpBullet); //将子弹添加到vector中 } } 2.删除子弹 vector<MBULLET>::iterator itei; //vector迭代器 for (itei = m_BulletList.begin(); itei != m_BulletList.end(); itei ++) //遍历所有子弹 { m_BulletList.erase(itei); //删除这个子弹 itei = m_BulletList.begin(); //删除一个结点后,为避免出错下次就从头检查 if (m_BulletList.empty()) break; //若删除结点后子弹vector已空则跳出循环 } 3.子弹遍历处理 vector<MBULLET>::iterator itei; //vector迭代器 for (itei = m_BulletList.begin(); itei != m_BulletList.end(); itei ++) //遍历所有子弹 { itei->pos.y -= itei->speed; //子弹飞行 } 要点五:碰撞检测 使用Windows API函数RectInRegion: vector<CEnimy>::iterator itei; //vector迭代器 for (itei = m_EnimyList.begin(); itei != m_EnimyList.end(); itei ++) //遍历所有敌机 { HRGN hrgn = ::CreateRectRgn(m_player->pos.x, m_player->pos.y, m_player->pos.x + 41, m_player->pos.y + 41); //得到飞机Region,图宽41高41 SetRect(&m_rect, itej->getPosition().x, itej->getPosition().y, itej->getPosition().x + 50, itej->getPosition().y + 50) //得到敌机rect,敌机宽50高50 if ( RectInRegion(hrgn, &m_rect) ) //两机相撞 { ……………………. //碰撞之后的各种处理 } } 让碰撞更加精确: 使用Windows API函数PtInRegion()和CreatePolygonRgn(),选取主角飞机的三个关键点的坐标放在POINT数组中,并将其作为参数代入 CreatePolygonRgn()中生成HRGN,在子弹与主角飞机做碰撞检测时只需判断子弹的中心点是否在这个Region中即可(PtInRegion())。 注意:CreateRectRgn()与CreatePolygonRgn()等创建Region的函数会占用系统资源,由于游戏的主渲染函数Render()是不断执行的,这样会造成资源浪费,因此在用完之后一定要释放:DeleteObject(region) 要点六:敌机直线飞行 最初想这个问题的时候,以为很好实现,脑子里马上想到 和 了。其实这样实现有问题,当起点和终点的连线斜率不是1或-1时就会出现意想不到的事情了,飞机并没有直接飞向终点,而是以斜率绝对值为1的路径飞过去,再水平或垂直飞向终点。 解决这个问题有几个方法,其中有一个方法是利用计算机图形学上的Bresenhem直线算法。该算法用于计算机画平面上的直线,算法如下: |m|<1的情况 1、输入线段的两个端点,并将左端点存储在(x0,y0)中; 2、将(x0,y0)装入帧缓冲器,画出第一个点; 3、计算常量dx,dy,2dy和2dy-2dx,并得到决策参数的第一个值: d0 = 2dy-dx 4、从k=0开始,在沿线路径的每个xk处,进行下列检测: 如果dk<0,下一个要绘制的点是(xk+1,yk),并且 dk+1 = dk+2dy 否则,下一个要绘制的点是(xk+1,yk+1),并且 dk+1 = dk +2dy –2dx 5、重复步骤4,共dx次。 利用此原理,实践在敌机直线飞行中的代码如下: void CEnimy::Move() { int deltaX = m_targetPos.x - m_pos.x; int deltaY = m_targetPos.y - m_pos.y; // 轨迹斜率 = 0 if ( !deltaX ) { if ( deltaY < 0 ) m_pos.y -= m_speed; else m_pos.y += m_speed; return; } // 轨迹斜率无穷大 if ( !deltaY ) { if ( deltaX < 0 ) m_pos.x -= m_speed; else m_pos.x += m_speed; return; } // 以下是用计算机图形学 Bresenham 算法计算两点间的直线轨迹 if ( abs(deltaX) > abs(deltaY) ) // 轨迹斜率 < 1 { if ( m_bFirstCalculate ) { m_Delta = 2 * abs(deltaY) - abs(deltaX); // d0 = 2 × dy - dx m_bFirstCalculate = false; } // 根据轨迹斜率判断是否要移动 Y 坐标 if ( m_Delta > 0 ) // < 0 时只改变 X 坐标,否则 X、Y 坐标都要变 { if ( deltaY < 0 ) m_pos.y -= m_speed; else m_pos.y += m_speed; m_Delta += 2 * abs(deltaY) - 2 * abs(deltaX); // 计算下一个 dn } else { m_Delta += 2 * abs(deltaY); // 计算下一个 dn } // X 坐标每一帧都要向目标移动 if ( deltaX < 0 ) m_pos.x -= m_speed; else m_pos.x += m_speed; } else // 轨迹斜率 > 1 { if ( m_bFirstCalculate ) { m_Delta = 2 * abs(deltaX) - abs(deltaY); // d0 = 2 × dx - dy m_bFirstCalculate = false; } // 根据轨迹斜率判断是否要移动 X 坐标 if ( m_Delta > 0 ) // < 0 时只改变 Y 坐标,否则 X、Y 坐标都要变 { if ( deltaX < 0 ) m_pos.x -= m_speed; else m_pos.x += m_speed; m_Delta += 2 * abs(deltaX) - 2 * abs(deltaY); // 计算下一个 dn } else { m_Delta += 2 * abs(deltaX); // 计算下一个 dn } // Y 坐标每一帧都要向目标移动 if ( deltaY < 0 ) m_pos.y -= m_speed; else m_pos.y += m_speed; } } 要点七:通过读取配置文件实现敌机的飞行轨迹 不同敌机以不同的轨迹飞行,实现的方法有很多,只要把轨迹上的几个关键点作为敌机的目标点,当到达这个目标点时,把目标列表中的下一个点作为下一个目标点,敌机继续向其飞行,这样就实现了敌机的不同轨迹飞行。但是要想把游戏中所有的敌机都写在代码中会很乱,不容易维护。VC++开发平台提供了两个函数:GetPrivateProfileSectionNames()和GetPrivateProfileString(),用来读取硬盘上的配置文件(.cfg),这样,每一架飞机的初始化信息可以写在.cfg文件中,通过一个循环算法来读取。 1. 函数说明: 这是将.cfg文件中所有的section names读取到一字符数组中: DWORD GetPrivateProfileSectionNames( LPTSTR lpszReturnBuffer, // 用来存放section names 的字符串指针 DWORD nSize, // 字符串的长度 LPCTSTR lpFileName // .cfg文件的路径 ); 这是读取某一section name中的某个字段的值: DWORD GetPrivateProfileString( LPCTSTR lpAppName, // 在这个section name中查找 LPCTSTR lpKeyName, // 要查找的字段名 LPCTSTR lpDefault, // 若查找失败的默认返回值 LPTSTR lpReturnedString, // 存放指定字段名所对应的值 DWORD nSize, // 存放返回值的字符串长度 LPCTSTR lpFileName // 在这个.cfg文件中查找 ); 2. 文件要求: .cfg文件的内容格式如下: [section name] key1=string key2=string 例如,在敌机的配置文件enimy.cfg中可以这么写: [ENIMY01] //这是进度号,不同进度加载不同敌机 tempoid=1 //这是图片号,根据需要加载不同的敌机图片 imageid=0 //这是图片的总帧数 imageframenum=2 //这是图片的宽度 imagewidth=100 //这是图片的高度 imageheight=50 //这是敌机生命值 hp=3 //这是敌机移动速度 speed=1 //这是敌机的初始位置 pos.x=512 pos.y=-50 //有两个目标点,即由两个点决定其轨迹 targetnum=2 //以下是目标点的坐标 targetpos0.x=512 targetpos0.y=192 targetpos1.x=240 targetpos1.y=600 其中,注释可以写入文件中,但不能与即将要读取的数据在同一行。 3. 代码例子: // 读取 CFG 文件中所有的敌机名称 // 读取完后m_sEnimyName中的字符串是每个section name的连接,两两之间用”\0”字符分开,如: // “enimy01.enimy02.enimy03”其中的点就是空字符 GetPrivateProfileSectionNames(m_sEnimyName, sizeof(m_sEnimyName), "data/enimy.cfg"); char *pStr = m_sEnimyName; // 用来保存当前的section name char returnedString[64]; m_iTempo++; // 每发动一波敌机,游戏进度加1 // 从 cfg 文件中找到进度等于 m_iTempo 的敌机 GetPrivateProfileString( pStr, "tempoid", "1", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); // 跳过以前已经加载过的敌机 while ( *pStr && atol( returnedString ) < m_iTempo ) { pStr += strlen( pStr ) + 1; // 这样处理,就能使pStr指向下一个section name GetPrivateProfileString( pStr, "tempoid", "1", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); } // 开始加载敌机 while ( *pStr ) { // 读取敌机的图片ID号 GetPrivateProfileString( pStr, "imageid", "0", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); int imageID = atol( returnedString ); // 读取敌机图片的总帧数 GetPrivateProfileString( pStr, "imageframenum", "2", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); int imageFrameNum = atol( returnedString ); // 读取敌机图片的宽度 GetPrivateProfileString( pStr, "imagewidth", "50", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); int imageWidth = atol( returnedString ); // 读取敌机图片的高度 GetPrivateProfileString( pStr, "imageheight", "50", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); int imageHeight = atol( returnedString ); // 读取敌机移动速度 GetPrivateProfileString( pStr, "speed", "1", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); int speed = atol( returnedString ); // 读取敌机的初始位置 POINT initPos; GetPrivateProfileString( pStr, "pos.x", "50", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); initPos.x = atol( returnedString ); GetPrivateProfileString( pStr, "pos.y", "0", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); initPos.y = atol( returnedString ); // 读取敌机运动轨迹上的各个目标点 int targetNum; // 目标点总数 GetPrivateProfileString( pStr, "targetnum", "1", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); targetNum = atol( returnedString ); POINT *targetArray; // 存放各目标点坐标 targetArray = new POINT[ targetNum ]; // 根据读取的目标点总数分配多少个坐标点 // 读取每一个目标点坐标 for ( int i = 0; i < targetNum; i++ ) { char buf[32]; sprintf( buf, "targetpos%d.x", i ); GetPrivateProfileString( pStr, buf, "0", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); targetArray[i].x = atol( returnedString ); sprintf( buf, "targetpos%d.y", i ); GetPrivateProfileString( pStr, buf, "0", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); targetArray[i].y = atol( returnedString ); } // 根据读取的敌机数据,创建敌机,并放入容器当中 CEnimy tmpEnimy( m_pGraph, m_pEnimyImageBuffer[imageID], 0x00000000, imageFrameNum, imageWidth, imageHeight ); tmpEnimy.Init( initPos.x, initPos.y, speed, targetArray, targetNum ); m_EnimyList.push_back( tmpEnimy ); //发射一架敌机 pStr += strlen( pStr ) + 1; // 取下一个字符串 GetPrivateProfileString( pStr, "tempoid", "1", returnedString, sizeof( returnedString ), "data/enimy.cfg" ); // 属于当前进度的敌机加载完后跳出while循环 if ( atol( returnedString ) > m_iTempo ) break; } // end of while (*pStr)

2013-04-30

DX绘制一个三角形的流程

一、 初始化Direct3D 1. 获得IDirect3D9 接口 获得一个IDirect3D9接口指针

2013-01-24

iOS工程师培养计划

培养计划 此计划为刀客移动工作室的 iOS 开发工程师培养计 划,总16 天左右

2013-01-24

DirectDraw的学习笔记

DirectDrawDirectDrawDirectDrawDirectDraw的学习笔记的学习笔记的学习笔记的学习笔记 开始看Wince下面的DDraw编程了,在wince的对应目录下面有几个例子: 在使用 DirextDraw时,需要首先创建一个对象DirectDraw 的实体,该对象实体代表了微机显示适配器。然后,使用接口所提供的方法来操作该对象实体,使之完成有关命令和任务。

2013-03-07

buttongif图标

buttongif图标是一个很多样式的button,你可以随心所欲的选择你想要的图标

2013-12-17

入口函数( main、WinMain)

入口函数( main、WinMain) 在C/C++中,我们知道有一个如下格式的函数: int main(int argc, _TCHAR* argv[]) { return 0; } 该函数是C/C++中的入口函数,而在WindowsAPI中也有自己的入口函数,该函数的格式为: int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { return 0; }

2013-01-24

基于windowsCE的win32动画制作

这是基于windowsCE的win32动画开发例子,运用平台vs2008,是windowsCE开发和入门的一个好的例子。

2013-03-10

用WPF 实现俄罗斯方块游戏

主要思想: 一、提供一个容器类(Container),用来作为方块活动的网格状区域。由于WPF自带Grid控件支持网格,因此就直接利用了。 1.Container类需要关联到Grid,活动区域;和waitingGrid等候区域(下一个出现的方块) 2.在Container类中实现消层的逻辑 二、提供一个方块基类(Box),7中方块全部从其派生。 1.每个方块包含4个Rectangle(小方格) 2.通过一个工厂类随机产生某个方块的实例 3.基类实现方块移动、变形、等逻辑、子类定义方块颜色、初始化方式,确定每个方格相对坐标。 4.在方块下降到底部触发OnBottom事件,Container接受此事件触发消行逻辑。Container类中OnGameover事件被界面层接受处理。

2013-01-27

飞秋FeiQ插件源代码

飞秋FeiQ会自动加载飞秋FeiQ工作目录下的Plugins目录下面的所有插件,这些插件不要求注册,程序会自动注册。只要把插件放进Plugins目录即可。所以编译好的插件,如果输出目录没有放Plugins目录,应手动拷贝到Plugins目录下面。飞秋FeiQ的插件目录,可以在点插件管理及设置中的打开插件目录,来查看位于哪个目录。

2013-01-25

C#结构与指针互相操作_结构与byte数组_所有字符串详解

结构体转byte数组: /**//// <summary> /// 结构体转byte数组 /// </summary> /// <param name="structObj">要转换的结构体</param> /// <returns>转换后的byte数组</returns> public static byte[] StructToBytes(object structObj) { //得到结构体的大小 int size = Marshal.SizeOf(structObj); //创建byte数组 byte[] bytes = new byte[size]; //分配结构体大小的内存空间 IntPtr structPtr = Marshal.AllocHGlobal(size); //将结构体拷到分配好的内存空间 Marshal.StructureToPtr(structObj, structPtr, false); //从内存空间拷到byte数组 Marshal.Copy(structPtr, bytes, 0, size); //释放内存空间 Marshal.FreeHGlobal(structPtr); //返回byte数组 return bytes; }

2013-12-20

Android教你如何一分钟实现下拉刷新功能demo

此为示例代码,详解讲解请参考 http://blog.csdn.net/sinyu890807/article/details/9255575

2014-01-03

图解密码技术 第三版.zip

本文来自《图解密码技术》一书 基本概念 信源、信宿、信道 加密、解密、密钥 对称密码、公钥密码、混合密码 单向散列(hash)函数、信息认证 数字签名 / 篡改和否认 伪随机数 信息传递时面临的风险: 窃听 -> 对称、公钥密码 篡改 -> 散列函数、消息认证、数字签名 伪装 -> 消息认证、数字签名 否认 -> 数字签名 有悖常识的几点: 不要使用保密的加密算法 使用低强度密码不如不用 任何密码都有可能被破解 密码只是安全的一部分(社工) 入门 凯撒密码 / 平移 / 暴力破解 简单替换密码 / 替换 / 频率分析 Enigma / 加密密码的密码 / 针对每日密钥的破解 对称密码 编码和异或 一次性密码和它的问题 使用对称密码时,我们通常默认密钥配送问题已解决 DES 全称Data Encryption Standard。于1977年在美国发明并使用。目前可以被暴力破解,因此不应再使用了。 DES以64bit为一个单位,使用和明文等长的密钥。 密钥每8位包含1位纠错码 基本结构使用Feistel网络 加密/解密步骤以轮为单位,DES有16轮 每轮运算不加密右半侧,同时右半侧比特和该轮密钥通过轮函数得到本轮加密左侧的密钥,和左侧做异或得到左侧密文 每轮加密后,进行左右对调,保证右侧的保密 解密时用相同结构,反向使用子密钥和轮函数即可 轮函数可以任意复杂 差分分析和线性分析衡量分组密码强度 三重DES 由IBM开发,步骤为DES加密 -> DES解密 -> DES加密。密钥长度是原来三倍,即168比特。 三步使用同一密钥,即向下兼容DES 根据1、3步是否使用同一密钥,分为DES-EDE2和DES-EDE3 处理速度慢 AES 全称Advanced Encrytion Standard,用来取代DES。由NIST开于1997年开始募集,将作为国家标准。算法要求开源免费,并在社群里公开评审,最终于2000年确定为Rijndael。 基本结构为SPN结构 明文分组长度固定为128bit、密钥长度可以是128、192、256比特三种 每轮分为SubBytes、ShiftRows、MixColumns、AddRoundKey四步 SubBytes,将4字节 * 4字节的矩阵与一个转换矩阵相乘,得到替换后的矩阵 ShiftRows,逐行做平移 MixColumns,逐列做矩阵运算 AddRoundKey,和轮密钥矩阵做对应位上的异或运算 解密时,除了AddRoundKey一步,其余均需要做逆运算 目前还没有针对Rijndael的有效攻击 避免使用DES,选择AES 分组密码的迭代模式 分组密码只能加密固定长度的密码。因此,需要有模式来迭代加密任意长度的明文。与分组密码相对的是流密码,对数据进行连续处理。 ECB 全称为Electronic CodeBook。是最简单直接的分组方式。将明文分组加密后直接得到对应位置的密文。不足的位用特定数据填充。 问题很明显,不要使用 相同的明文分组会得到相同的密文分组 攻击者无需破译密码也可通过修改密文操纵明文,比如替换或删除分组 CBC 全称Cipher Block Chaining。和ECB的最大不同在于明文分组加密前会和上一个密文分组做一次异或运算。开头的明文分组会和一个随机序列做XOR。 一个密文分组的损坏会影响关联的两个分组的解密 比特的缺失将会影响整个密文的解密 操纵初始化向量反转某一位比特可以反转第一个密文分组的某一位 填充提示攻击,攻击padding部分 SSL/TLS使用CBC模式保证通信机密 CTS使用最后一个密文填充不足的明文部分 CFB 全程Cipher FeedBack模式。和CBC模式的区别在密文分组先加密,再和下一个明文做异或运算。实际上明文分组和密文分组间只相差了一个异或运算。很类似一次性密码本的模式。 解密时,需要对密文分组和初始向量做加密操作 重放攻击,替换密文分组为原有分组,可使得解密出的明文为原有明文 OFB 全称Output-FeedBack模式。和CFB很像,区别在于OFB每次做XOR的密钥流仅来自于上一次的密钥,和密文分组无关。因为密钥流可以提前准备好,分组加密过程可以是并行的。 第一次的密钥来自初始化向量 速度快 如果碰巧密钥加密后和加密前一样,那么之后的密钥就会是同一个值 CTR 全称CounTeR。CTR和OFB类似,区别在于它的密钥流来自于累加的计数器。密文分组来自于密钥流和明文分组的XOR运算。 计数器由nonce和序号两部分各8字节组成,nonce是随机生成的,序号是从1累加的。 和OFB一样,加密解密速度快,结构简单 CTR的密钥流在选定nonce后就确定了,因此可以以任意顺序并行加密、解密 公钥密码 解决了对称密码的密钥配送问题。 密钥配送问题 事先共享,在现实生活中传送 密钥配送中心,集中式管理用户密钥,用其加密临时的会话密钥 使用Diffie-Hellman密钥交换 使用公钥密码 公钥密码 使用加密密钥(公钥)加密,使用解密密钥(私钥)解密,避免密钥的泄露。 发送者使用加密密钥 接收者使用解密密钥 加密密钥可以公开 解密密钥一定要保密 目前所使用的公钥密码RSA来自于1978年的发明。流程上, 接收者生成公私钥对,发送公钥给发送者 发送者使用公钥加密明文 接收者使用私钥解密密文 公钥密码有两个问题: 认证公钥的合法性 处理速度慢 RSA 利用了数论中求解离散对数困难且耗时的特点。 加密,使用密文=明文 ^ E mod N。E和N组合成公钥。 解密,使用明文=密文 ^ D mod N。D和N组合成密钥。 生成N、E、D和顺序如下: 寻找互质的两个大数p和q,N为二者的乘积 p-1和q-1的最小公倍数记为L 寻找比L小的和L互质的数,即为E 寻找比L小的和E乘积取模L为1的数,即为D 因为解密时有对N取模操作,因此加密的明文不能大于N。 攻击方式 破解密文 -> 求解离散对数很难 暴力破解D -> 比特位太长,很难破解 通过E求解D,只要知道p和q就能算出D -> 不知道p和q的组合 -> 对N质因数分解很难 中间人攻击里,攻击者可以替换掉原本的公钥,发送给接收者,使用自己的私钥解密,从而实现攻击。这时需要证书保证公钥的权威性。 选择密文攻击里,攻击者可以利用服务端返回的错误消息收集加密算法信息。RSA-OAEP会在明文开头加上明文散列值和填充位,解密时发现散列值和内容对不上时,会隐藏错误信息。 除了RSA外,还有ElGamal方式、Robin方式、ECC(椭圆曲线密码)等公钥密码。它们分别利用了mod N下求离散对数,mod N下求平方根,和椭圆曲线上做乘法运算逆运算在数学上很难求解的特点。 FAQ Q: 和对称密码的强度对比 A: 达到同等强度,RSA大致需要密钥是AES长度的20倍 Q: RSA使用的质数会用完么 A: 512bit的质数数目大约是10 ^ 150。足够使用。 Q: RSA破解难度如何? A: 和大整数质因数分解一样难度 Q: 要保证RSA强度,N的长度要达到多少位 A: 2048bit,4096bit更好 混合密码系统 用对称密码加密明文 用公钥密码加密上述对称密码的密钥(通常用随机数生成器得到,只用于此次会话) 公钥密码的密钥由外部赋予(证书) 密码软件PGP、HTTPS中使用的SSL/TLS就使用了混合密码系统。当然它们还包含数字签名、认证、私钥管理等更多处理。 类似混合密码系统,后面要介绍的数字签名、证书、消息认证、伪随机数生成也都是基础密码技术的组合。 单向散列函数 将任意长度的消息转换到固定长度散列 具有抗碰撞性,即找到具有相同散列函数的消息很困难 单向性,即无法从三列中还原原信息 MD4、MD5 全称Message Digest。由Rivest设计于1990和1991年。能够产生128bit的散列值。它们的强抗碰撞性已被攻破,不建议使用。 RIPEMD-160 1996年设计,是欧盟RIPE项目的修订版,能产生160bit长度的散列值。比特币中使用的散列函数就是RIPEMD-160。 SHA SHA于1993年由NIST设计,在1995年发布了SHA-1修订版,能够产生160bit的散列值。它的强抗碰撞性已被攻破,也不建议使用。 SHA-2于2002年发布,它是包括SHA-256,SHA-384和SHA-512的集合,分别产生256、384和512bit的散列值。目前未被攻破。SHA-2的几种散列长度来自SHA-256和SHA-512的组合。 SHA-3作为SHA-1的升级替代算法,和AES一样,由NIST公开选拔,并在2012年确定为一个叫Keccak的算法。之后会和SHA-2并存一段时间。 Keccak Keccak可以输入任意长度的数据,产生任意长度的散列值。实现上,Keccak采用海绵结构,有吸收和挤出两阶段。 吸收阶段,按分组长度r逐段读入消息内容,和内部状态做异或运算,之后和长度为c的内部状态一起交给函数f做“搅拌”。完成一轮处理,输出作为内部状态继读入输入的消息分组。 挤出阶段,内部消息r和c逐段和函数f做运算,一段段输出散列值。 Keccak的双工结构下,输入和输出可以同时进行。Keccak内部状态由5 5 z的一个三维比特数组组成,共有b个bit。Keccak的本质就是实现一个充分搅拌上述数组的函数f。SHA-3中使用的是Keccak-f[1600]函数。其中b就是内部状态的bit数。函数的每一轮包含θ、ρ、π、χ、ι5步。循环轮数为12 + 2 * log2(b / 25)。 θ,将不同两个column的各5个bit通过异或运算加起来,再和当前位做异或替换 ρ,各比特沿z轴方向进行平移 π,对一个slice上的5 * 5个比特做旋转、轮换操作 χ,对一个row上的各位做某个逻辑运算 ι,用某个轮常数对所有比特做异或运算,避免对称性 Keccak采用的海绵结构和此前各散列算法使用的MD结构(循环执行压缩函数)方法截然不同,这也是它最后成为标准的一个原因。目前还未出现针对Keccak的有效攻击手段。 攻击方式 利用文件的冗余性,构造一大堆和想要内容一样的数据,找到和原内容散列值一样的结果。 原像攻击,给定散列值,找到具有该散列值的任意消息 第二原像攻击,给定消息1,找到和消息1有相同散列值的消息2 生日攻击,攻击散列算法的“强抗碰撞性”(寻找两个具有相同散列值的消息),利用了从有N个元素的集合中依次取并放回M个元素,两次取到同一元素的概率约为根号N的特点。大大减少暴力破解需要的次数。 消息认证 可以同时防止消息的伪装和篡改。消息认证码简称MAC(Message Authentication Code)。可以简单理解成需要密钥参与的单向散列过程。在使用时: 发送者伴随消息发送计算出的MAC 接受者对消息通过共享密钥计算出MAC值,进行对比,一致则表示认证成功 这个密钥不能被中间人获取! 使用消息认证码(MAC)机制的场景有: SWIFT IPSec SSL/TLS 在认证加密时,Encrypt-then-MAC表示对密文计算MAC值,从而能判断密文是由知道明文和密钥的人生成的。除了Encrypt-then-MAC外,还有Encrypt-and-MAC和MAC-then-Encrypt两种方式。 HMAC HMAC即Hash MAC,是使用单向散列函数构造认证码的方法。分为下面几步: 在密钥后填充0到长度达到单向散列函数的分组长度 填充后的密钥和ipad序列做XOR运算,ipad序列是00110110为单位循环的比特序列 组合在消息头部,并计算出散列值 填充后的密钥和opad做XOR运算,opad是01011100位单位循环的比特序列 结果拼在散列值后面 根据5的结果计算最终的散列值 应对攻击方式 消息认证需要解决重放攻击的问题,即再次发送相同的消息和MAC值。可以在消息中额外带上序号、时间戳,或先发送一个nonce一次性随机数保证相同的消息也会有完全不同的MAC值。 密钥推测攻击,应保证不能根据MAC值推测出双方使用的密钥,必须使用安全、高强度的伪随机数生成器。 另外,消息认证无法解决下面的问题: 向第三方证明,密钥的共享只在通信的双方,无法证明给第三方 同样的,不能防止通信的一方否认消息 数字签名 和公钥密码相反的使用方式: 发布者使用私钥加密消息,私钥保密 使用发布者的公钥可以解密消息,公钥公开 签名有两种方式:对消息签名和对消息的散列值签名。它们主要区别在签名的对象不同。基本过程是: 生成公、私钥对,发送公钥给接收者 使用私钥加密消息/消息的hash值,得到签名 发送消息和签名给接收者 接收者使用公钥解密,对比消息/消息hash值,验证发送者身份 在签名中,密钥只是起着“保证消息发送者的可靠来源目的的”,被复制并不影响它发挥作用。同时,由于不知道私钥,修改消息后无法伪造消息的签名。 实际应用数字签名的地方有很多: 安全信息公告 软件下载 公钥证书,确保公钥的合法来源 SSL/TLS,交换公钥的过程 数字签名基于公钥密码,因此数字签名的实现方式因采用的公钥密码而异,如RSA、ElGamal、ECDSA(椭圆曲线密码)。对数字签名的攻击可以基于单向散列函数或是公钥密码。 不要对不清楚来源的数据做数字签名 对消息的散列值函数做数字签名 数字签名无法解决验证签名正确性的公钥被伪造的问题,因为公钥正确性也依赖于数字签名技术。这里需要证书以及公钥基础设施PKI这种社会学的基础设施辅助。 证书 证书即公钥证书,用来验证公钥密码和数字签名的公钥,由认证机构(CA)发布,认证机构可以是政府机关、一般企业或个人。证书的发布过程包括: 申请人生成一对密钥,并把公钥发送给CA CA验证申请人身份 通过验证后,CA使用自己的私钥对公钥施加数字签名并生成证书 使用申请人证书的使用者通过CA的公钥验证申请人的公钥是否合法 验证通过后,使用公钥完成公钥密码或数字签名 PKI是为了能够更有效运用公钥制定的一系列规范的总称。PKI组成要素有3个:使用PKI的用户、认证机构、仓库。 用户,分为注册公钥的用户和使用注册公钥的用户 CA,包括生成密钥、验证本人身份、验证公钥合法性、作废证书 仓库,是保存证书的数据库 其中认证机构做了以下事情: 生成密钥对,可以由用户或是CA生成,若是CA生成,需要根据规范发送私钥给用户 注册证书,用户根据规范申请证书,认证机构根据业务准则生成符合X.509规范的证书 作废证书,因为私钥丢失等原因需要作废证书时,需要认证机构制作CRL(Certificate Revocation List,证书作废清单),PKI用户总需要从CA获取最新的CRL,以确认自己拿到的公钥证书是否有效。 认证机构的证书认证 认证机构的公钥证书可以由其他的认证机构施加数字签名。这个关系可以嵌套很多层,比如部门认证机构、分公司认证机构、总公司认证机构。一直往上直到根CA,可以对自己的公钥做自签名。 从而,在验证证书合法性上,也会出现从上至下的验证过程。 证书的攻击 对证书的攻击即对数字签名的攻击。 对施加数字签名前的公钥攻击 注册相似人名进行攻击 窃取CA的私钥 伪装成CA发放证书进行攻击,认证机构本身的可信度也很重要 利用发送CRL的时间间隔,窃取了使用者的私钥,当使用者联系CA发布CRL时,有一定的时间间隔 同样利用CRL,使用合法私钥发送消息后,发送CRL作废自己的公钥,否认自己之前发送的消息 不可能在完全不可信的状态下创建出信任关系,除非以已经存在的信任关系为基础。 密钥 密钥长度(DES:56bit,三重DES:112bit或168bit,AES:128、192、256bit 对称密码和公钥密码用于确保机密性,消息认证码和数字签名使用的密码用于认证,防止篡改内容和伪装身份 只使用一次的密钥称为会话密钥,重复使用的密钥称为主密钥。 密码学用途的随机数生成器必须为密码学用途专门设计 定期改变会话密钥可以减少密钥泄露的损失 保存密钥时,使用KEK(Key Encrypting Key)方式保存密钥可以减少管理密钥的数目。 Diffie-Hellman密钥交换 Diffie-Hellman密钥交换里,通信的双方通过交换一些可以公开的消息,就能够生成共享的密钥。 确定一个非常大的质数P,寻找P的生成元(原根)G 通信双方各自找1个1 ~ P-2的随机数A、B,生成G ^ A mod P与G ^ B mod P,发送给对方 对方用收到的数字根据自己选的随机数做乘方运算,得到相等的值作为密钥 它同样利用了离散对数问题难以快速求解的特点。这种交换方法可以做中间人攻击,可以用数字签名、证书等方式应对。 基于口令的密码(PBE) 基于口令的密码避免了:记忆CEK -> 记忆KEK -> 记忆KEK的KEK的死循环。使用好记忆的口令配合盐生成CEK。使用过程如下: 使用随机数生成器生成盐(随机数),加上用户口令,使用单向散列函数得到KEK 使用KEK加密会话使用的CEK 保存好盐以及使用KEK加密的会话秘钥 盐的目的是避免字典攻击 口令虽然便于生成,但是强度不高,因此需要格外地小心保管 可以对KEK迭代使用单向散列函数得到最后的KEK(拉伸),这将加大攻击者的攻击负担 生成安全的口令 使用只有自己知道的信息 不包括别人见过的信息 不包括可以很容易推测的信息 不应该重复使用口令,容易受牵连影响 物理保存是可以的,但要注意安全 可以使用口令生成和管理工具(比如1Password) 随机数生成 随机数生成在密码学中很常用: 生成密钥 生成分组密码的初始化向量 生成CTR模式的nonce 生成盐 随机数至少需要具有下面的属性: 随机等概性 无状态,即无法从上一个推测下一个,生成序列无法重现 由于计算机构成的抽象世界是离散的,内部状态有限,不能满足无状态的特点,因此只能称作伪随机数生成器。基于计算机硬件的随机数生成器可以认为是“真”随机数,它通常提前储存在一个随机数池中,在需要的时候直接从池中取用。伪随机数生成器根据随机的种子(seed)通过算法将内部状态转化为最终的随机数。 线性同余法,以当前随机数为内部状态(初始值为种子),(A x Rn + C) mod M,计算下一个值。其中A、C、M都需要事先选好,线性同余法生成的随机数数列具有可预测性,即不需要知道种子也可以推测下随机数值 单向散列函数,利用单向散列函数保护内部状态,以种子为初始值,逐次递加得到新的内部状态,再通过单向散列函数输出为随机数 密码法,类似单向散列函数,使用密钥加密内部状态输出也可以作为随机数,此时保护内部状态的加密算法和密钥 ANSI X9.17中,使用AES和三重DES作为密码算法 初始化内部状态 使用当前时间生成掩码 掩码和内部状态做XOR 加密3的输出,作为随机数输出 对加密后的输出与掩码做XOR 加密5的结果作为新的内部状态 PGP介绍 PGP全程Pretty Good Privacy,编写于1990年,具备现代密码软件所需的几乎所有功能。OpenPGP是一对密文和数字签名进行定义的标准规格。 加密和解密 加密时,使用混合密码系统的流程: 用伪随机数生成会话密钥 用接收者的公钥加密会话密钥 压缩消息,并使用对称密码加密,密钥为上面生成的会话密钥 将加密后的密钥和密文拼接在一起 将4的结果转换为文本数据,即为报文数据 解密时,PGP的私钥通过用户口令加密保存。在收到密文时: 输入接收者的口令 求口令的散列值,生成用户解密私钥的秘钥 解密得到私钥 将报文数据转换为二进制,并拆解成加密的会话密钥和压缩的密文 用自己的私钥解密得到会话密钥 用会话密钥解密密文 解压缩明文得到原始消息 生成数字签名 同样,生成数字签名时: 输入接收者的口令 求口令的散列值,生成用户解密私钥的秘钥 解密得到私钥 使用单向散列函数计算消息散列值 对散列值签名,即使用私钥加密 拼合签名和消息,进行压缩 (可选)转换二进制为文本数据,即最后的报文数据 类似地,验证时: 转换为二进制文件,解压缩数据 分解出签名和消息两部分 使用公钥解密签名,得到散列值 使用单向散列函数计算消息散列值,对比3中的散列值 相等即验证成功 生成数字签名并加密 实际情况下,我们往往需要使用加密算法加密数字签名中的原消息。实现步骤是上两节的组合。即先进行数字签名,再对签名结果加密。 验证过程是相反的,先解密密文得到签名结果,再验证数字签名。 信任网 PGP确认公钥合法性的方法不依赖于认证机构颁发证书,而是采用所有者信任级别构成信任网(也叫信任圈、朋友圈)的方式,让用户自己决定该信任谁。建立信任有三种方式: 通过自己的签名来确认。用户在通过其他方式(比如线下)确认公钥可信任后,对该公钥加上自己的数字签名。由于PGP中,使用者本人的公钥是绝对信任,被施加签名的公钥因此可信任。注意:这并不代表被施加签名的公钥所有者被完全信任 通过自己完全信任的数字签名进行确认。即完全信任某个公钥进行的数字签名,用户可对当前信任的每个公钥所有者设置信任级别,级别为完全信任时,所有者公钥施加签名的公钥也会被信任。 通过有限信任的多个数字签名进行确认。在设置信任级别为有限信任时,有限信任的公钥都施加数字签名后,新的公钥才会被信任。 通过上面三种方式,PGP使用者可以构建起自己的信任网,从而根据自己的决定信任某个公钥。 SSL/TLS TLS是SSL的后续版本,但在大多数情况下,可以统一写成SSL/TLS。SSL/TLS可以承载应用层协议,保证应用层传输的安全性,HTTP就是其中一种。其余SSL/TLS可以承载的应用层协议还包括SMTP、POP3等等。 SSL于1994年在网景公司开发,在1995年发布了SSL3.0版本,后被发现会导致POODLE攻击。TLS是IETF在1999年作为SSL3.1发布。2006年发布TLS1.1,之后又发布了TLS1.2。 HTTPS中SSL/TLS要保证以下三点: 保证消息传输中不被窃听 -> 对称密码加密消息,公钥密码加密对称密码的密钥 保证消息传输中不被篡改 -> 消息认证码 保证消息传输双方的合法性 -> 数字签名生成证书 通信过程 下面的流程以TLS1.2为例。TLS协议分为两层: TLS握手协议,位于上层,处理除加密的部分。可以进一步分为: 握手协议,负责在客户端和服务器间协商密码算法和共享密钥 密码规格变更协议,向通信对象传达变更密码方式 警告协议,在发生错误时将错误传达给对方 应用数据协议,将TLS上承载的应用数据传达给通信对象 TLS记录协议,位于底层,处理加密的部分。使用了对称密码和消息认证码,但具体的算法和密钥需要通信双方具体协商 TLS记录协议 记录协议负责数据的压缩、加密、数据认证,工作方式如下: 分割消息为较小的片段,再分段压缩,压缩方式需要协商决定 对压缩过的消息进行消息认证,加上MAC值。为了避免重放攻击,在计算MAC值时,加上了片段的编号。其中的单向散列函数的算法、使用的密钥都需要协商确定 把MAC值和压缩过的消息片段组合在一起,使用对称密码加密。迭代模式使用CBC模式,CBC模式的初始化向量通过主密码生成。对称密码的算法、密钥则需要协商决定 上述经过加密的数据,再加上数据类型、版本号、压缩后的长度,构成最终的报文数据。数据类型就是之前提到的TLS握手协议的4类子协议 握手协议 握手协议负责生成对称密码中的共享密钥以及交换证书。因为握手的整个过程都是明文进行的,因此需要使用公钥密码或是Diffie-Hellman密钥交换。整个握手协议有下面几步: ClientHello,客户端发送一些信息给服务器,便于协商算法和密钥 可用版本号,即支持的SSL/TLS版本号 客户端生成的随机数,在后面的步骤会用到 会话ID,在需要重新使用以前的会话时用到 客户端可用的密码套件清单 客户端可用的压缩方式清单 当前时间 ServerHello,服务器根据客户端传来的信息,选择合适的算法和密码套件,返回的消息中带有下面几条 使用的版本号 服务端生成的随机数,后面步骤会用到 会话ID,作用同上 使用的密码套件 使用的压缩方式 当前时间 Certificate,非匿名通信时,服务器发送自己的证书,以及对服务器证书签名的CA的证书 ServerKeyExchange,当Certificate消息不足时,服务器通过此消息传递额外信息 CertificateRequest,需要进行客户端认证时,服务端发送此消息,并带上服务器能理解的证书类型、CA名称清单。 ServerHelloDone,服务器发送此消息结束服务器的返回 Certificate,作为CertificateRequest的回应,客户端发送自己的证书,交给服务器验证 ClientKeyExchange,密码套件包含RSA时,会发送经过服务器公钥加密的预备主密码;密码套件包含Diffie-Hellman密钥交换时,会发送Diffie-Hellman密钥交换中的公开值。预备主密码(pre-master secret)是客户端生成的随机数,之后会用做生成主密码的种子。根据预备主密码,通信双方计算出相同的主密码。主密码会用做以下用途: 对称密码的密钥 消息认证码的密钥 CBC模式中的初始化向量 CertificateVerify,在服务器发送CertificateRequest时,通过此消息发送客户端使用自己私钥签名的主密码和握手协议传输消息的散列值。证明自己是客户端证书的持有人。 ChangeCipherSpec,客户端发送,表示切换密码开始,实际上是密码规格变更协议的一类报文 Finished,握手结束,此时已使用切换后的密码套件来加密发送。 ChangeCipherSpec,Finished。来自服务器,作用同上。 通过上面的步骤,双方达成了下面的目标: 客户端获得了服务器的公钥,完成了服务器认证 服务器获得了客户端公钥,完成了客户端认证(如果需要的话) 生成了对称密码的密钥 生成了消息认证码中的共享密钥 密码规格变更协议 用于在一开始从明文通信切换到使用密码套件沟通。 警告协议 用在握手协议异常、消息认证码错误、无法解压数据等异常情况。 应用数据协议 通信对象间传递应用数据。 主密码 主密码根据预备主密码(pre-master secret)或Diffie-Hellman密钥交换的公开值生成。生成的主密码用于生成对称密码的密钥、消息认证码的密钥、CBC模式的初始化向量。 对SSL/TLS的攻击 SSL/TLS框架性的特点让它不依赖于某个特定的密码技术,因此对特定密码技术的攻击对SSL/TLS本身影响不大 心脏出血漏洞,发现于2014年,利用TLS心跳拓展对请求的数据大小没有检查,可以获取内存中与请求无关的信息。是OpenSSL实现的漏洞。 POODLE攻击,利用CBC中的填充提示攻击,发现于2014年SSL3.0中。 FREAK攻击,可以在密码套件协商时,利用中间人攻击,强制使用强度很低的RSA Export Suites。从而在加密后,暴力破解明文。 对伪随机数生成器的攻击 利用之前提过的CRL 总结 密码技术因为人类的不完美而必定不会完美。 对称密码,使用相同密钥加密、解密,保证消息机密性。目前主要使用AES。 公钥密码,使用不同密钥加密、解密,作用同上。使用最广泛的是RSA,还有相关的Diffie-Hellman密钥交换 单向散列函数,将消息转为固定长度散列值的技术,保证消息完整性,目前使用SHA2和SHA3(Keccak) 消息认证码,结合单向散列函数和对称密码,保证消息完整性并认证消息,但无法防御否认。目前主要使用HMAC 数字签名,结合单向散列函数和公钥秘钥,保证完整性,不可否认性和认证消息。是公钥证书采用的技术 伪随机数生成器,配合上述技术使用,需要保证不可预测性和不可重现性 密码技术从某种角度看是一种压缩技术: 密钥是机密性的压缩 散列值是消息完整性的压缩 认证值时认证的压缩 随机数种子是不可预测性的压缩 比特币 比特币来自于Satoshi Nakamoto(中本聪,化名)的一篇论文,并于2009年开始实际运用。比特币是一种基于P2P网络的支付结算系统。用户通过它进行进行价值转移。 地址,将公钥使用散列函数求散列值得到,地址都以1开头,剩下内容 不包含O,0,1和I。 钱包,即比特币客户端,可以生成密钥对,公钥用于收款,密钥用于付款 区块链,保存了比特币所有交易记录的账簿,若干交易组成一个区块,在区块头有所有交易的散列值,以及上一个区块的散列值,有交易添加时会触发区块头的散列值变化,并链式传递下去 交易,收、付款方各自生成密钥对,付款方创建交易“地址A向地址B转账x BTC”,并用自己的私钥签署数字签名,之后广播至P2P网络中,完成交易。比特币使用的数字签名基于椭圆曲线DSA,方程为x^2 = y^3 + 7 挖矿,向区块链中添加新区块的行为被称为挖矿,第一个挖矿成功的矿工会获得挖矿奖励和区块所有交易的手续费。为了证明自己确实完成了规定工作,矿工需要进行工作量证明(PoW),即生成的区块头中,前一区块头的散列值必须以若干位的0开头,这个工作需要投入大量的计算资源。区块大约每10分钟添加一个,为了避免通货膨胀,所需的0的个数会不断调整。 根据协议规定,挖矿奖励每4年减少一半 当区块链上同时出现分支时,P2P网络会选择计算量大的分支进行工作 比特币的匿名性只限于交易地址 附录:椭圆曲线 椭圆曲线(EC)源自于求椭圆弧长的椭圆积分的反函数。 定义椭圆曲线上的加法运算 椭圆曲线上的离散对数(ECDLP) - 已知点G和点xG,求整数x 有限域上的离散对数,对点进行模运算 椭圆曲线Diffie-Hellman密钥交换 椭圆曲线ElGamal密码 椭圆曲线DSA(ECDSA)

2019-05-16

iPhoneUI windows mobile 6.0滑动解锁(C#)

运行平台windows mobile 6.0专业版的SDK和VS2008,这是一个学习Iphone UI的很好例子。

2013-04-19

C#多线程串口通信

这是一个非常经典的C#串口多线程实例,把部分代码发送来让大家看看 using System; using System.IO; using System.IO.Ports; using System.Collections; using System.Threading; namespace Termie { /// <summary> CommPort class creates a singleton instance /// of SerialPort (System.IO.Ports) </summary> /// <remarks> When ready, you open the port. /// <code> /// CommPort com = CommPort.Instance; /// com.StatusChanged += OnStatusChanged; /// com.DataReceived += OnDataReceived; /// com.Open(); /// </code> /// Notice that delegates are used to handle status and data events. /// When settings are changed, you close and reopen the port. /// <code> /// CommPort com = CommPort.Instance; /// com.Close(); /// com.PortName = "COM4"; /// com.Open(); /// </code> /// </remarks> public sealed class CommPort { SerialPort _serialPort; Thread _readThread; volatile bool _keepReading; //begin Singleton pattern static readonly CommPort instance = new CommPort(); // Explicit static constructor to tell C# compiler // not to mark type as beforefieldinit static CommPort() { } CommPort() { _serialPort = new SerialPort(); _readThread = null; _keepReading = false; } public static CommPort Instance { get { return instance; } } //end Singleton pattern //begin Observer pattern public delegate void EventHandler(string param); public EventHandler StatusChanged; public EventHandler DataReceived; //end Observer pattern private void StartReading() { if (!_keepReading) { _keepReading = true; _readThread = new Thread(ReadPort); _readThread.Start(); } } private void StopReading() { if (_keepReading) { _keepReading = false; _readThread.Join(); //block until exits _readThread = null; } } /// <summary> Get the data and pass it on. </summary> private void ReadPort() { while (_keepReading) { if (_serialPort.IsOpen) { byte[] readBuffer = new byte[_serialPort.ReadBufferSize + 1]; try { // If there are bytes available on the serial port, // Read returns up to "count" bytes, but will not block (wait) // for the remaining bytes. If there are no bytes available // on the serial port, Read will block until at least one byte // is available on the port, up until the ReadTimeout milliseconds // have elapsed, at which time a TimeoutException will be thrown. int count = _serialPort.Read(readBuffer, 0, _serialPort.ReadBufferSize); String SerialIn = System.Text.Encoding.ASCII.GetString(readBuffer,0,count); DataReceived(SerialIn); } catch (TimeoutException) { } } else { TimeSpan waitTime = new TimeSpan(0, 0, 0, 0, 50); Thread.Sleep(waitTime); } } } /// <summary> Open the serial port with current settings. </summary> public void Open() { Close(); try { _serialPort.PortName = Settings.Port.PortName; _serialPort.BaudRate = Settings.Port.BaudRate; _serialPort.Parity = Settings.Port.Parity; _serialPort.DataBits = Settings.Port.DataBits; _serialPort.StopBits = Settings.Port.StopBits; _serialPort.Handshake = Settings.Port.Handshake; // Set the read/write timeouts _serialPort.ReadTimeout = 50; _serialPort.WriteTimeout = 50; _serialPort.Open(); StartReading(); } catch (IOException) { StatusChanged(String.Format("{0} does not exist", Settings.Port.PortName)); } catch (UnauthorizedAccessException) { StatusChanged(String.Format("{0} already in use", Settings.Port.PortName)); } catch (Exception ex) { StatusChanged(String.Format("{0}", ex.ToString())); } // Update the status if (_serialPort.IsOpen) { string p = _serialPort.Parity.ToString().Substring(0, 1); //First char string h = _serialPort.Handshake.ToString(); if (_serialPort.Handshake == Handshake.None) h = "no handshake"; // more descriptive than "None" StatusChanged(String.Format("{0}: {1} bps, {2}{3}{4}, {5}", _serialPort.PortName, _serialPort.BaudRate, _serialPort.DataBits, p, (int)_serialPort.StopBits, h)); } else { StatusChanged(String.Format("{0} already in use", Settings.Port.PortName)); } } /// <summary> Close the serial port. </summary> public void Close() { StopReading(); _serialPort.Close(); StatusChanged("connection closed"); } /// <summary> Get the status of the serial port. </summary> public bool IsOpen { get { return _serialPort.IsOpen; } } /// <summary> Get a list of the available ports. Already opened ports /// are not returend. </summary> public string[] GetAvailablePorts() { return SerialPort.GetPortNames(); } /// <summary>Send data to the serial port after appending line ending. </summary> /// <param name="data">An string containing the data to send. </param> public void Send(string data) { if (IsOpen) { string lineEnding = ""; switch (Settings.Option.AppendToSend) { case Settings.Option.AppendType.AppendCR: lineEnding = "\r"; break; case Settings.Option.AppendType.AppendLF: lineEnding = "\n"; break; case Settings.Option.AppendType.AppendCRLF: lineEnding = "\r\n"; break; } _serialPort.Write(data + lineEnding); } } } }

2013-12-15

rdlc报表例子

自己随便修改啦一份代码,能够在报表上显示数据和和曲线图,通过数据集获取的

2013-12-17

七夕礼物-让屏幕开满玫瑰花

让电脑屏幕开满玫瑰花的程序,免费共享,提供源代码

2014-01-03

FastDraw 绘图库

用于写绘图库的一个很好的例子,里边写了很多实现的方法,主要是针对WinCE下的,DirectDraw开发

2013-03-22

Android瀑布流照片墙实现,体验不规则排列的美感Demo

此为示例代码,详细讲解请参考: http://blog.csdn.net/guolin_blog/article/details/10470797

2014-01-03

Android系统架构概述

Android系统 = Linux内核 + Android运行时。 Android系统使用的Linux内核包含了一些专用驱动,例如Logger、Binder、Ashmem、Wakelock、Low-Memory Killer和Alarm等,这些Android专用驱动构成了Android运行时的基石。Android运行时从下到上又包括了HAL层、应用程序框架层和应用程序层。HAL层主要是为规避GPL而设计的,它将将硬件驱动分成内核空间和用户空间两部分,其中用户空间两部分采用的是商业友好的Apache License。应用程序框架层主要包括系统服务,例如组件管理服务、应用程序安装服务、窗口管理服务、多媒体服务和电信服务等。应用程序框架进一步又分为C/C++和Java两个层次,Java代码运行Dalvik虚拟机之上,并且通过JNI方法和C/C++交互。应用程序层主要就是由四大组件Activity、Service、Broadcast Receiver和Content Provider构成,它们是应用开发的基础。这个PPT从一个通用的应用程序架构开始,概述Android系统的专用驱动、HAL、关键服务、Dalvik、窗口机制和四大组件等。这个PPT 作为前面第1个PPT的延续,帮助进一步了解Android系统的具体实现。

2014-01-03

LibUsbDotNet

最近在用C#调试USB程序,libusb源码是C语言的,C#用起来不方便,偶然在网上看到了LibUsbDotNet,这是开源的项目,下载后参考Example,用起来非常方便。安装后所有的例子和资源以及帮助文件都在里边,不要积分给个好评!

2013-12-19

C#典型模块与项目实战大全源码1—18

全套项目运行在VS2010上,涵盖了ASP.Net4.0、ASP.net MVC、ADO.net Entity Framework、WPF、LINQ、Silverlight、Windows Forms等微软主流实际开发应用技术。全部压缩在一起的,全部代码在此。

2013-05-04

MicroCOS_II

邵贝贝老师翻译的第二版的光盘,MicroCOS_II

2013-05-29

CLR.via.C#.(中文第3版)(自制详细书签)

CLR.via.C#.(中文第3版)(自制详细书签)Part2 CLR via C#(第3版) Jeffrey Richter 著 周靖 译 出版时间:2010年09月 页数:800 介绍 享有全球盛誉的编程专家Jeffrey Richter,这位与Microsoft .NET开发团队合作长达8年时间的资深顾问,在本书中和读者分享他编程生涯中积累的所有丰富经验和心得,他的独到、睿智的见解,他的远见卓识,为开发人员构建健壮、可靠和具有良好响应能力的应用程序与组件奠定了良好的基础。 《CLR via C#(第3版) 》针对.NET Framework 4.0和多核编程进行了全面更新和修订,是帮助读者深入探索和掌握公共语言运行时、C#和.NET开发的重要参考,同时也是帮助开发人员构建任何一种应用程序(如Microsoft Silverlight、ASP.NET、Windows Prensentation Foundation、Web服务和控制台应用程序)的良师益友。 本书涵括以下主题: · 构建、部署应用程序、组件和共享程序集,并对它们进行版本管理 · 理解基元类型、值类型和引用类型的行为,从而最高效地定义和使用它们 · 使用泛型和接口来定义可重用的算法 · 高效使用特定的CLR类型——委托、枚举、定制attribute、数组和字符串 · 理解垃圾回收器是如何管理内存资源的 · 使用线程池、任务、取消、计时器和异步I/O操作来设计响应性强、稳定性高和伸缩性大的解决方案 · 借助于异常处理来进行状态管理 · 使用CLR寄宿、AppDomain、程序集加载、反射和C#的dynamic类型来构造具有动态扩展能力的应用程序 本书作者作者Jeffrey Richter,.NET和Windows编程领域当之无愧的大师和权威,以著述清楚明了,行文流水,言简意赅著称,在国内具有相当高的知名度,他的著作之一《Windows核心编程(第5版)》屡获殊荣,在国内外都享有盛誉,在国内因年销量过万而获得中国书刊业发行协会“2009年度全行业畅销书品种”称号。 目录 第1章 CLR的执行模型 1.1 将源代码编译成托管模块 1.2 将托管模块合并成程序集 1.3 加载公共语言运行时 1.4 执行程序集的代码 1.4.1 IL和验证 1.4.2 不安全的代码 1.5 本地代码生成器:NGen.exe 1.6 Framework类库 1.7 通用类型系统 1.8 公共语言规范 1.9 与非托管代码的互操作性 第2章 生成、打包、部署和管理应用程序及类型 2.1 .NET Framework部署目标 2.2 将类型生成到模块中 2.2.1 响应文件 2.3 元数据概述 2.4 将模块合并成程序集 2.4.1 使用Visual Studio IDE将程序集添加到项目中 2.4.2 使用程序集链接器 2.4.3 为程序集添加资源文件 2.5 程序集版本资源信息 2.5.1 版本号 2.6 语言文化 2.7 简单应用程序部署(私有部署的程序集) 2.8 简单管理控制(配置) 第3章 共享程序集和强命名程序集 3.1 两种程序集,两种部署 3.2 为程序集分配强名称 3.3 全局程序集缓存 3.4 在生成的程序集中引用一个强命名程序集 3.5 强命名程序集能防范篡改 3.6 延迟签名 3.7 私有部署强命名程序集 3.8 “运行时”如何解析类型引用 3.9 高级管理控制(配置) 3.9.1 发布者策略控制 第4章 类 型 基 础 4.1 所有类型都从System.Object派生 4.2 类型转换 4.2.1 使用C#的is和as操作符来转型 4.3 命名空间和程序集 4.4 运行时的相互联系 第5章 基元类型、引用类型和值类型 5.1 编程语言的基元类型 5.1.1 checked和unchecked基元类型操作 5.2 引用类型和值类型 5.3 值类型的装箱和拆箱 5.3.1 使用接口更改已装箱值类型中的字段(以及为什么不应该这样做) 5.3.2 对象相等性和同一性 5.4 对象哈希码 5.5 dynamic基元类型 第6章 类型和成员基础 6.1 类型的各种成员 6.2 类型的可见性 6.2.1 友元程序集 6.3 成员的可访问性 6.4 静态类 6.5 分部类、结构和接口 6.6 组件、多态和版本控制 6.6.1 CLR如何调用虚方法、属性和事件 6.6.2 合理使用类型的可见性和成员的可访问性 6.6.3 对类型进行版本控制时的虚方法的处理 第7章 常量和字段 7.1 常量 7.2 字段 第8章 方法 8.1 实例构造器和类(引用类型) 8.2 实例构造器和结构(值类型) 8.3 类型构造器 8.3.1 类型构造器的性能 8.4 操作符重载方法 8.4.1 操作符和编程语言互操作性 8.5 转换操作符方法 8.6 扩展方法 8.6.1 规则和原则 8.6.2 用扩展方法扩展各种类型 8.6.3 ExtensionAttribute 8.7 分部方法 8.7.1 规则和原则 第9章 参 数 9.1 可选参数和命名参数 9.1.1 规则和原则 9.1.2 DefaultParameterValueAttribute和OptionalAttribute 9.2 隐式类型的局部变量 9.3 以传引用的方式向方法传递参数 9.4 向方法传递可变数量的参数 9.5 参数和返回类型的指导原则 9.6 常量性 第10章 属性 10.1 无参属性 10.1.1 自动实现的属性 10.1.2 合理定义属性 10.1.3 对象和集合初始化器 10.1.4 匿名类型 10.1.5 System.Tuple类型 10.2 有参属性 10.3 调用属性访问器方法时的性能 10.4 属性访问器的可访问性 10.5 泛型属性访问器方法 第11章 事件 11.1 设计要公开事件的类型 11.1.1 第一步:定义类型来容纳所有需要发送给事件通知接收者的附加信息 11.1.2 第二步:定义事件成员 11.1.3 第三步:定义负责引发事件的方法来通知事件的登记对象 11.1.4 第四步:定义方法将输入转化为期望事件 11.2 编译器如何实现事件 11.3 设计侦听事件的类型 11.4 显式实现事件 第12章 泛型 12.1 Framework类库中的泛型 12.2 Wintellect的Power Collections库 12.3 泛型基础结构 12.3.1 开放和封闭类型 12.3.2 泛型类型和继承 12.3.3 泛型类型同一性 12.3.4 代码爆炸 12.4 泛型接口 12.5 泛型委托 12.6 委托和接口的逆变和协变泛型类型实参 12.7 泛型方法 12.7.1 泛型方法和类型推断 12.8 泛型和其他成员 12.9 可验证性和约束 12.9.1 主要约束 12.9.2 次要约束 12.9.3 构造器约束 12.9.4 其他可验证性问题 第13章 接口 13.1 类和接口继承 13.2 定义接口 13.3 继承接口 13.4 关于调用接口方法的更多探讨 13.5 隐式和显式接口方法实现(幕后发生的事情) 13.6 泛型接口 13.7 泛型和接口约束 13.8 实现多个具有相同方法名和签名的接口 13.9 用显式接口方法实现来增强编译时类型安全性 13.10 谨慎使用显式接口方法实现 13.11 设计:基类还是接口? 第14章 字符、字符串和文本处理 14.1 字符 14.2 System.String类型 14.2.1 构造字符串 14.2.2 字符串是不可变的 14.2.3 比较字符串 14.2.4 字符串留用 14.2.5 字符串池 14.2.6 检查字符串中的字符和文本元素 14.2.7 其他字符串操作 14.3 高效率构造字符串 14.3.1 构造StringBuilder对象 14.3.2 StringBuilder的成员 14.4 获取对象的字符串表示:ToString 14.4.1 指定具体的格式和语言文化 14.4.2 将多个对象格式成一个字符串 14.4.3 提供定制格式化器 14.5 解析字符串来获取对象:Parse 14.6 编码:字符和字节的相互转换 14.6.1 字符和字节流的编码和解码 14.6.2 Base-64字符串编码和解码 14.7 安全字符串 第15章 枚举类型和位标志 15.1 枚举类型 15.2 位标志 15.3 向枚举类型添加方法 第16章 数组 16.1 初始化数组元素 16.2 数组转型 16.3 所有数组都隐式派生自System.Array 16.4 所有数组都隐式实现IEnumerable,Icollection和IList 16.5 数组的传递和返回 16.6 创建下限非0的数组 16.7 数组的访问性能 16.8 不安全的数组访问和固定大小的数组 第17章 委托 17.1 初识委托 17.2 用委托回调静态方法 17.3 用委托回调实例方法 17.4 委托揭秘 17.5 用委托回调许多方法(委托链) 17.5.1 C#对委托链的支持 17.5.2 取得对委托链调用的更多控制 17.6 委托定义太多啦(泛型委托) 17.7 C#为委托提供的简化语法 17.7.1 简化语法1:不需要构造委托对象 17.7.2 简化语法2:不需要定义回调方法 17.7.3 简化语法3:局部变量不需要手动包装到类中即可传给回调方法 17.8 委托和反射 第18章 定制attribute 18.1 使用定制attribute 18.2 定义自己的attribute类 18.3 attribute的构造器和字段/属性的数据类型 18.4 检测定制attribute 18.5 两个attribute实例的相互匹配 18.6 检测定制attribute时不创建从Attribute派生的对象 18.7 条件attribute类 第19章 可空值类型 19.1 C#对可空值类型的支持 19.2 C#的空接合操作符 19.3 CLR对可空值类型的特殊支持 19.3.1 可空值类型的装箱 19.3.2 可空值类型的拆箱 19.3.3 通过可空值类型调用GetType 19.3.4 通过可空值类型调用接口方法 第20章 异常和状态管理 20.1 定义“异常” 20.2 异常处理机制 20.2.1 try块 20.2.2 catch块 20.2.3 finally块 20.3 System.Exception类 20.4 FCL定义的异常类 20.5 抛出异常 20.6 定义自己的异常类 20.7 用可靠性换取开发效率 20.8 指导原则和最佳实践 20.8.1 善用finally块 20.8.2 不要什么都捕捉 20.8.3 得体地从异常中恢复 20.8.4 发生不可恢复的异常时回滚部分完成的操作——维持状态 20.8.5 隐藏实现细节来维系契约 20.9 未处理的异常 20.10 对异常进行调试 20.11 异常处理的性能问题 20.12 约束执行区域(CER) 20.13 代码契约 第21章 自动内存管理(垃圾回收) 21.1 理解垃圾回收平台的基本工作原理 21.1.1 从托管堆分配资源 21.2 垃圾回收算法 21.3 垃圾回收与调试 21.4 使用终结操作来释放本地资源 21.4.1 使用CriticalFinalizerObject类型确保终结 21.4.2 SafeHandle类型及其派生类型 21.4.3 使用SafeHandle类型与非托管代码进行互操作 21.5 对托管资源使用终结操作 21.6 什么会导致调用Finalize方法 21.7 终结揭秘 21.8 Dispose模式:强制对象清理资源 21.9 使用实现了Dispose模式的类型 21.10 C#的using语句 21.11 一个有趣的依赖性问题 21.12 手动监视和控制对象的生存期 21.13 对象复活 21.14 代 21.15 用于本地资源的其他垃圾回收功能 21.16 预测需求大量内存的操作能否成功 21.17 编程控制垃圾回收器 21.18 线程劫持 21.19 垃圾回收模式 21.20 大对象 21.21 监视垃圾回收 第22章 CLR寄宿和AppDomain 22.1 CLR寄宿 22.2 AppDomain 22.2.1 跨越AppDomain边界访问对象 22.3 卸载AppDomain 22.4 监视AppDomain 22.5 AppDomain FirstChance异常通知 22.6 宿主如何使用AppDomain 22.6.1 可执行应用程序 22.6.2 Microsoft Silverlight富Internet应用程序 22.6.3 Microsoft ASP.NET Web窗体和XML Web服务应用程序 22.6.4 Microsoft SQL Server 22.6.5 更多的用法只局限于你自己的想象力 22.7 高级宿主控制 22.7.1 使用托管代码管理CLR 22.7.2 编写健壮的宿主应用程序 22.7.3 宿主如何拿回它的线程 第23章 程序集加载和反射 23.1 程序集加载 23.2 使用反射构建动态可扩展应用程序 23.3 反射的性能 23.3.1 发现程序集中定义的类型 23.3.2 类型对象的准确含义 23.3.3 构建Exception派生类型的一个层次结构 23.3.4 构造类型的实例 23.4 设计支持加载项的应用程序 23.5 使用反射发现类型的成员 23.5.1 发现类型成员 23.5.2 BindingFlags:筛选返回的成员种类 23.5.3 发现类型的接口 23.5.4 调用类型的成员 23.5.5 一次绑定、多次调用 23.5.6 使用绑定句柄来减少进程的内存耗用 第24章 运行时序列化 24.1 序列化/反序列化快速入门 24.2 使类型可序列化 24.3 控制序列化和反序列化 24.4 格式化器如何序列化类型实例 24.5 控制序列化/反序列化的数据 24.5.1 如何在基类没有实现ISerializable的前提下定义一个实现它的类型 24.6 流上下文 24.7 将类型序列化为不同的类型以及将对象反序列化为不同的对象 24.8 序列化代理 24.8.1 代理选择器链 24.9 反序列化对象时重写程序集和/或类型 第25章 线程基础 25.1 Windows为什么要支持线程 25.2 线程开销 25.3 停止疯狂 25.4 CPU发展趋势 25.5 NUMA架构的机器 25.6 CLR线程和Windows线程 25.7 使用专用线程执行异步的计算限制操作 25.8 使用线程的理由 25.9 线程调度和优先级 25.10 前台线程和后台线程 25.11 继续学习 第26章 计算限制的异步操作 26.1 CLR线程池基础 26.2 执行简单的计算限制操作 26.3 执行上下文 26.4 协作式取消 26.5 任务 26.5.1 等待任务完成并获取它的结果 26.5.2 取消任务 26.5.3 一个任务完成时自动启动一个新任务 26.5.4 任务可以启动子任务 26.5.5 任务内部揭秘 26.5.6 任务工厂 26.5.7 任务调度器 26.6 Parallel的静态For,ForEach和Invoke方法 26.7 并行语言集成查询(PLINQ) 26.8 执行定时计算限制操作 26.8.1 太多的计时器,太少的时间 26.9 线程池如何管理线程 26.9.1 设置线程池限制 26.9.2 如何管理工作者线程 26.10 缓存线和伪共享 第27章 I/O限制的异步操作 27.1 Windows如何执行I/O操作 27.2 CLR的异步编程模型(APM) 27.3 AsyncEnumerator类 27.4 APM和异常 27.5 应用程序及其线程处理模型 27.6 异步实现服务器 27.7 APM和计算限制操作 27.8 APM的注意事项 27.8.1 在没有线程池的前提下使用APM 27.8.2 总是调用EndXxx方法,而且只调用一次 27.8.3 调用EndXxx方法时总是使用相同的对象 27.8.4 为BeginXxx和EndXxx方法使用ref,out和params实参 27.8.5 不能取消异步I/O限制操作 27.8.6 内存消耗 27.8.7 有的I/O操作必须同步完成 27.8.8 FileStream特有的问题 27.9 I/O请求优先级 27.10 将IAsyncResult APM转换为Task 27.11 基于事件的异步模式 27.11.1 将EAP转换为Task 27.11.2 APM和EAP的对比 27.12 编程模型的泥沼 第28章 基元线程同步构造 28.1 类库和线程安全 28.2 基元用户模式和内核模式构造 28.3 用户模式构造 28.3.1 易失构造 28.3.2 互锁构造 28.3.3 实现简单的Spin Lock 28.3.4 Interlocked Anything模式 28.4 内核模式构造 28.4.1 Event构造 28.4.2 Semaphore构造 28.4.3 Mutex构造 28.4.4 在一个内核构造可用时调用一个方法 第29章 混合线程同步构造 29.1 一个简单的混合锁 29.2 自旋、线程所有权和递归 29.3 混合构造的大杂烩 29.3.1 ManualResetEventSlim和SemaphoreSlim类 29.3.2 Monitor类和同步块 29.3.3 ReaderWriterLockSlim类 29.3.4 OneManyLock类 29.3.5 CountdownEvent类 29.3.6 Barrier类 29.3.7 线程同步构造小结 29.4 著名的双检锁技术 29.5 条件变量模式 29.6 用集合防止占有锁太长的时间 29.7 并发集合类

2013-12-27

使用标准GDI实现游戏品质的动画系统

说到实现游戏品质的动画,很多人会立刻想到DirectX,没错DirectDraw很强大,但是并不是必须用DirectDraw才行。动画后面的理论和技巧都是一样的,这和末端使用什么API没有太大关系(如果那API不是太~~慢的话)。就笔者实现的NewImage Lib的测试结果,内部所有像素数据的存储和运算都纯软件实现,最后一步输出到屏幕使用GDI的性能比DirectDraw低不到10%,在Window9X系统上要低20%左右,这对很多软件来说是绝对可以接受的。

2013-01-24

北航软院2012年数据结构与C语言程序设计试题

北京航空航天大学2012年硕士研究生入学考试试题 “数据结构与C语言程序设计”(科目代码:991) 一、填空题(本题共20分,每小题各2分) 1.从总体上说,“数据结构”课程主要研究 三个方面的内容。 2.若对某线性表最常用的操作是在表中插入元素或者删除表中元素,则对于顺序存储结构和链式存储结构这两种存储结构而言,线性表应该采用 。 3.在长度为n的非空队列中进行插入或者删除操作的时间复杂度用大O符号表示为 。 4.若一棵度为4的树中度为1、2、3和4的结点个数分别为4、2、1和1,则该树中叶结点的个数为 。 5.若某二叉树的中序遍历序列为B,A,F,D,G,C,E,按层次遍历序列为A,B,C,D,E,F,G,则该二叉树的后序遍历序列为 。 6.将一棵结点总数为n、且具有m个叶结点的树转换为一棵二叉树以后,该二叉树中右子树为空的结点有 个。 7.对于图G=(V,E) 与 G^=(V^,E^),若有V^包含于V,E^包含于E,则称G^是G的 。8.在顺序表(6,15,30,37,65,68,70,72,89,99)中采用折半查找法查找元素37,与表中进行过比较的元素依次是 。 9.若已知n个关键字值具有相同的散列函数值,并且采用线性探测再散列法处理冲突,那么,将这n个关键字值全部散列到初始为空的地址空间中,发生散列冲突的次数是 。10.若长度为n的序列K=(k1,k2,…,kn)当且仅当满足ki≤k2i并且ki≤k2i+1(1≤i≤n/2)时,则称该序列为一个小顶堆积(Heap)。根据该定义,序列(26,5,77,1,61,11,59,48,15,19)对应的小顶堆积是 。

2013-12-17

vs2008对C++代码有智能提示

Visual+Assist+X+10.6.1837+破解版+支持VS2010是一个很好的插件能让vs2008对C++代码有智能提示

2013-01-25

跨链技术践行者的留言板

发表于 2020-01-02 最后回复 2020-04-17

想用零知识证明实现隐私保护,有用过libsnark库的给个教程

发表于 2019-05-13 最后回复 2019-05-13

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人 TA的粉丝

提示
确定要删除当前文章?
取消 删除