1.怎样将电网频率用于多媒体取证?面向音频取证的闪烁闪烁电网频率检测与增强【有源码】
2.充分理解Linux GCC 链接生成的Map文件
3.在手机中制作边IMY格式的铃声(闪烁,振动)有特效更好
4.求C语言小游戏源程序
5.c++表白代码烟花
怎样将电网频率用于多媒体取证?面向音频取证的光之光电网频率检测与增强【有源码】
多媒体来源取证与真伪取证的方法有很多种,其中一种有趣的源码源码取证方法是通过分析音频中的电网频率(俗称电流声)在音频中留下的痕迹,可以有效地检测音视频文件的编译产生时间,并进行各种取证。闪烁闪烁该方法由武汉大学的光之光fmscms直播秀场源码华光等老师提出,文末有源代码,源码源码供感兴趣的编译老师和同学参考。
电网频率(electric network frequency,闪烁闪烁ENF)是光之光指交流电网的传输频率,我国标称值为 Hz(其他国家也有 Hz),源码源码是编译被动多媒体取证的重要判据。它之所以能够成为取证判据,闪烁闪烁主要有三个原因:首先,光之光交流电和用电器的源码源码活动会产生以标称频率为基波的声学震动以及照明设备的灯光闪烁,这些不易被人感知的振动和闪烁可以被音视频录制设备捕捉,形成一种“被动不可见水印”;其次,电网频率在标称值附近随机小范围波动,赋予了电网频率轨迹的独特性;第三,电网频率波动模式在同一电网内部所有位置保持一致,赋予了电网频率波动的一致性。经过多年的发展,电网频率判据已可用于音视频文件产生时间溯源、篡改检测与定位、地理位置溯源、重放攻击检测等取证任务。目前,电网频率分析是录音文件产生时间被动溯源的唯一有效方法。
然而,基于电网频率判据的数字取证研究仍面临一些困难。首先,并不是任意设备在任意条件下都能成功捕捉电网频率;其次,电网频率相对于录音内容和环境噪声十分微弱,在无法控制录音条件的实际取证任务中难以进行有效提取和分析。针对这两个问题,本项工作分别提出了录音文件中电网频率的检测和增强算法,并建立并开源了目前最大的“电网频率-武汉大学”(ENF-WHU)真实世界录音文件数据集,用于对相关算法进行全面评估。
为确认待验录音文件中是否存在电网频率以保证后续取证分析有效,本工作从信号检测理论出发,逐步放宽对信号模型的假设,推导出电网频率的网站伪原创源码一系列理论和实际检测器。其中,只有本工作提出的TF-detector为恒虚警率(CFAR)检测器。
由于信号模型和特性的巨大差异,现有语音(或其他信号)的增强的方法均无法有效增强电网频率信号。对于检测到电网频率的录音文件,为提升其可用性,本工作提出了一种适合电网频率随机小范围缓慢波动特性的鲁棒滤波算法(robust filtering algorithm,RFA),将观测到的带噪电网频率信号调制到正弦频率调频(SFM)解析信号的瞬时频率,并引入核函数,通过处理其产生的正弦时频分布,逐个恢复去噪后的电网频率观测样本,显著提升了电网频率轨迹的质量,为后续取证分析提供了可靠数据。
以上工作为提升电网频率判据在实际取证中的可靠性,促进基于电网频率判据的录音文件取证从实验室走向实际应用提供了技术支撑。相关成果于和年分别发表在IEEE Transactions on Information Forensics and Security,作者为武汉大学华光、张海剑、廖晗、王清懿、叶登攀。
ENF-WHU数据集和MATLAB程序已开源:
github.com/ghuawhu/ENF-...
Guang Hua and Haijian Zhang*, “ENF signal enhancement in audio recordings,” IEEE Transactions on Information Forensics and Security, vol. , pp. -, .
Guang Hua, Han Liao, Qingyi Wang, Haijian Zhang*, and Dengpan Ye, “Detection of electric network frequency in audio recordings – from theory to practical detectors,” IEEE Transactions on Information Forensics and Security, vol. , pp. -, .
充分理解Linux GCC 链接生成的Map文件
简单来说,map文件就是通过编译器编译之后,生成的程序、数据及IO空间信息的一种映射文件,里面包含函数大小,入口地址等一些重要信息。从map文件我们可以了解到:
生成map文件是链接器ld的功能,有两种方式可以生成map文件:
使用GNU binutils,必须通过设置正确的标志来显式地请求生成映Map文件。使用LD将Map打印到输出到output.map:
作为一个简单程序的例子,你可以使用以下命令链接编译单元:
为什么要了解Map文件:
在本文中,我想突出说明链接器Map文件是多么简单,以及它可以教给我们关于正在处理的程序的一些知识。
固件工程师很少在调试时使用构建过程生成的Map文件。然而,答案有时就在这个Map文件中。
Map文件提供了有价值的信息,可以帮助您理解和优化内存。我强烈建议为在生产环境中运行的竞价王星源码任何固件保存该文件。
Map文件是整个程序的符号表。让我们深入研究它,看看它有多简单,以及如何有效地使用它。我将尝试用一些例子来说明,这些例子都是用GNU binutils来描述的。
LED闪烁程序:
还有什么比我们的老朋友LED闪烁程序示例解释一下Map文件的基础知识更好的呢?
为了了解Map文件,我们使用Nordic SDK中的LED闪烁程序来编译,并修改它以添加对atoi的调用。然后,我们将使用Map文件来分析这两个程序之间的差异。
下面就是示例的main.c文件:
编译:
生成的Map文件有多行 ,尽管它只是在闪烁发光二极管。这么多行不可能看不见,里面一定有一些重要的信息……
现在让我们修改程序,添加对atoi的调用,我们不直接使用整数作为延迟函数的参数,而是将其编码为字符串并使用atoi解码,然后作为参数传给延时函数。
经过编译,整个程序从字节变成了字节。
我们能够想到调用atoi会带来更多的代码,但是%程序大小的增加是巨大的!
深入研究Map文件:
在下面的部分中,我将使用代码片段来解释Map文件的不同部分。
Archives linked:
下面是Map文件的第一行内容:
上述信息的格式如下:
上面内容的意思是crt0这个文件中会调用exit函数,exit函数在exit.o这个目标文件中,exit.o目标文件是被链接在libc_nano.a这个库文件里的。
为什么是这样,不在本文的讨论范围内,但是你的工具链(这里是GNU工具链)确实提供了一些标准库。它们可用于提供atoi等标准功能,在这个例子中,我指定链接器使用nano.spec文件,这就是为什么标准函数都来自libc_nano.a。
现在,比较两个生成的map文件,发现的第一个区别是程序中包含了一些其他的存档成员:atoi,它本身需要_strtol_r,_strtol_r本身又需要_ctype_:
现在,我们对实际包含在程序中的文件以及它们存在的原因有了更好的理解。让我们来看看这个文件里面还有什么!
Memory configuration:
Map文件中最直接的主题屋源码网信息是实际的内存区域,这些区域具有位置、大小和访问权限:
Linker script and memory map:
内存配置之后是Linker script and memory map,这个很有趣,因为它给出了程序中符号的详细信息。在我们的例子中,它首先指示text区域的大小及其内容(text是我们编译的代码,而data是程序数据)。
在这里,中断向量(在.isr_vector下)出现在可执行文件的开头,定义在gcc_startup_nrf.S中:
这些行给出了每个函数的地址和大小。在上面,你可以读取bsp_board_led_invert的地址,它来自boards.c.o(如你所猜测的,board.c的编译单元),在text区域中它的大小为0x字节。这样,我们就可以定位程序中使用的每个函数。
我的常量字符串_delay_ms_str在程序初始化时显然包含在程序中,只读数据作为rodata保存在链接器脚本中指定的FLASH区域中(存储在Flash中,而不是复制在RAM中,因为它是常量)。我可以在这行下面找到:
我还注意到_ctype_的包含在text区域中增加了0x字节的只读数据
标准库是开源的( 链接),我们很容易就能找出它占用那么多空间的原因。我深入到atoi的内部(可重入版本的atoi_r,见下文),它是直接调用的strtol_r:
对于strtol_r,它实际上比仅仅将字符转换为整数更复杂,因为还使用ctype来执行类型检查。ctype的工作方式是使用一个表,其中ASCII符号类型存储在一个数组中。下面是ctype的主要部分,并附上我的注释:
有趣的是,atoi的添加不仅增加了代码的大小(text区域),还增加了数据的大小(data区域)。分析两个Map文件,我可以很容易地发现之前被链接器丢弃的数据:
现在你可能已经注意到函数名以_r结尾,例如在调用strtol_r时,该后缀表示可重入性。有关可重入性的文档可以在 newlib源代码中找到。总而言之,即使同一函数已经在另一个进程中执行,国外精品成品源码也可以调用可重入函数,而不会干涉执行。从文档中可以看到如下描述:
Each function which uses the global reentrancy structure uses the global variable _impure_ptr, which points to a reentrancy structure.
在我们的例子中,我们需要新的全局变量来调用可重入函数:atoi_r。
最后要记住的一点信息是:初始化变量必须保存在Flash中,但它们在Map文件中会出现在RAM中,因为它们在进入主函数之前被复制到RAM中。在这里,符号__data_start__和__data_end__跟踪RAM中用于保存初始化变量的区域,这些值存储在Flash中,起始位置为0xd0:
Discarded sections:
如果链接器没有找到对函数和变量的任何引用,编译后包含在程序中的函数和变量并不总是最终二进制文件的一部分,它们将会被删除但是仍然会出现在Map文件的Discarded input sections 部分。例如,下面是一些定义在boards.c中的函数,它们永远不会被调用并因此被丢弃:
Common symbols:
这个部分没有出现在我们的Map文件中,但它值得一提。
Common symbols(通用符号)是可以在代码中的任何地方使用的非常量全局变量(non-constant global variables)。您可能知道,使用全局变量通常不是一个好的实践,因为它们使代码更难维护。确实如此,作用域是全局的,每个外部模块可以修改任何全局变量的值,访问时必须考虑到这一点。将变量隔离到一个模块中,使用static关键字,通常更好地确保创建变量的模块完全负责其状态。
现在,如果您希望使程序更安全并防止访问某些全局变量,请查看Map文件部分。如果某些变量不需要声明为全局变量,您可能希望将它们转换为静态变量。
Map文件有几种可能的用法:大多数时候,一个地址后面对应着一个函数,我们希望通过这个地址去了解一些问题。例如,它可以是硬故障处理程序(Hard Fault handler)中的程序计数器(Program Counter)。其他时候,你也会遇到调试一些不明确的行为,最终发现你的程序意外地写入了一个出界数组(数组越界)。当有了ELF文件时,arm-none-eabi-nm对于这些事情也非常有用,它提供了按大小排序符号的选项。
但有些时候,它甚至在你有可执行文件之前就很有用了……
Debugging a linking error:
Map文件是在构建代码(.o文件)链接在一起的时候生成的,这意味着它可以有助于解决链接过程中出现的错误。我记得在几个Flash页面中包含一个引导加载程序,在某些情况下,我想使用atoi,但引导加载程序不再编译,因为没有更多的可用空间。
使用前面的示例,假设我现在只有0x字节的Flash。编译第一个示例时,如果没有atoi,就不会出现问题,但是第二个例子会溢出我们的Flash:
是不是很讨厌?atoi只是一个很简单的函数而已,居然就出现这种问题。但正如我们前面所提到的,使用libc_nano.a需要比预期更多的Flash空间。
让我们来实现自己版本的atoi,其实也没那么难。以下是编译后的结果(config CUSTOM_ATOI):
这个方法是不是很好?现在可以将代码塞进0x字节的Flash,以满足我们的(假)需求。
分析Map文件可以让我们了解很多正在编写的代码,这是改进固件的第一步。
可以使用一些工具来解析Map文件并获得程序的汇总视图,后面有时间和大家好好聊聊。
在手机中制作边IMY格式的铃声(闪烁,振动)有特效更好
IMY编辑好像也不用什么软件.用记事本写好了.然后改下扩展名就好啦.简单点说我也像HTML一样是一种语言.让手机来解释我.我是一种标准.让别人遵从的.这东西贴完了我自己去编辑一下看看.
为了大家更好测试提供原文件.就给震动一个,别的都是音乐:
/d/9cdb0acdabfb4dbbe
写在前边.有些朋友什么都不求去搞明白,那就看前边这些吧;
操作法一.把刚下载的imy 放到手机里的Audio文件夹,切忌手机里的Audio文件夹
然后点击写短信(不是彩信)(可以用自己的手机编辑铃声然后保存看是不是这个文件家.我自己测试了是这个文件夹)
操作法二.直接找到你发在手机里的IMY文件.发送文件,以短信或者增强短信形式.这样文件就加进去了.手机短信里会多出来一个音乐符,你写短信时要注意.引着朋友往下看就成.把文件放在后边.其它放中间也成.
发给他们试试吧.还想明白点的朋友往下看
一、IMY本来是音乐
一个网友如是说:
我第一个手机就是爱立信的TSC,后来买了个T送BF,开始对imy的铃声也是一无所知,后来看了很多东西,终于有所领悟,其实T的和弦铃声太小,我倒觉得imy铃声也不错,于是写点体会.欢迎指正. imelody(imy)标准非常灵活,音域跨了9个8度,种不同音长, 我一般用Mobile Music进行MIDI/IMY/RTTTL各种的转换。
创建imy铃声的过程如下,以CS的炸弹声为例:
建立一个记事本按一下格式,写入代码:
BEGIN:IMELODY
VERSION:1.2
FORMAT:CLASS1.0
NAME:Bomb (你铃声的名字,方便你记忆,不过在手机里显示的名字还是.imy前的文件名)
BEAT:
STYLE:S0
VOLUME:V
MELODY:(ledonvibeonbackon*7e4ledoffvibeoffbackoffr1@5) (ledonvibeonbackon*7e4ledoffvibeoffbackoffr2@) (ledonvibeonbackon*7e4ledoffvibeoff backoffr3@)(ledonvibeonbackon*7e4ledoffvibeoffbackoffr5@)vibeon(ledonbackon*7e5ledoffbackoff@0) (音符代码)
END:IMELODY
最后保存为*.imy用红外线传入你的或其他机器保存,就可以享受到带震动及闪屏的铃声了
大家可以对这个一起好好研究研究~
二、IMY被恶搞
另个网友如是说:
黑屏震动死机音符 谁有imy源代码
今天朋友给我发了两条短信。内容如下:
1.警告:这条短信不要往下翻了。
再翻就会黑屏一个小时。
(无奈本人好奇心太重,翻了一下,结果就黑屏了。按按键还一闪一闪的。结果只能扣电池。郁闷。。。)
2.相信又能让手机失灵的短信吗?这条就能让你梦想成真。
不要往下翻了。
再翻你就得扣电池了。
再此警告!!
(可惜这次我又看了,结果手机狂振不止。没办法,扣电池吧。更加郁闷。。。 )
真邪门了,短信能让手机这样!!
上网查了一下,原因找到了:本人的手机是山寨机!!!
为什么这条短消息会让山寨手机黑屏呢?这和手机的MTK平台有关。
大部分“山寨机”的操作系统使用的是MTK平台。这个MTK平台,因为价格低廉,让不少国内生产MP3音乐播放器的厂家,一夜之间,都能生产手机。
这条短信的格式是:(空行)注意(空行)你的手机将黑屏一小时(空行)你信不信……(空行到底)。在这些空行里,隐含了一个音乐提示符。正是这个音乐提示符,让手机黑屏的。这个音乐提示符,是可以测试盗版和正版的一个组件——和电脑上微软XP操作系统一样,不是正版的软件,就会黑屏。
在MTK解决方案的手机中对于声音文件,都带有一个震动接口,也就是把震动命令放进铃声,使用该铃声的时候,手机会自动震动了!同震动的原理,MTK解决方案中,可能除了震动接口,还有黑屏的命令接口(当然,很可能仅仅是漏洞),在声音文件中加入该命令就可以使手机黑屏了!
三、进一步扩大战果
手机格式化代码!!!!!!!!!!
BEGBEGIN:IMELODY
VERSION:1.2
FORMAT:CLASS1.0
COMPOSER:MIK()Fomat
BEAT:
MELODY:backoffbackofffbackoffbackoffbackoffbackoffbackoffbackoffbackoff
("+<melody>+"@)"
手机黑屏代码
BEGIN:IMELODY
BEAT:
MELODY:(ledoffbackoffvibeoffr5ledoffbackoffvibeoffr5@)
END:IMELODY
手机狂震代码
BEGIN:IMELODY
VERSION:1.2
FORMAT:CLASS1.0
BEAT:
MELODY:(ledoffledonbackoffbackonvibeon@0)
END:IMELODY
向你们的“山寨朋友”发起猛攻吧
大家慎用..后果自负
imy 放到手机里的Audio文件夹,切忌手机里的Audio文件夹
然后点击写短信(不是彩信)(可以用自己的手机编辑铃声然后保存看是不是这个文件家.我自己测试了是这个文件夹)
选项:
以上各个代码未曾在短信中直接写入源代码发送试验,格式化代码请勿轻易尝试!如果要在短信中直接写入格式化代码,请在尝试其他代码后,确保无危险后才试验。
插入对象我的铃声选取刚才那个IMY文件发送
原理IMY是索爱最早支持的一种春代码的单音节铃声,可以用代码调用手机的解码芯片发出一些声音甚至一些核心指令
四、明白一点(基本标准)
imy的基本格式:
BEGIN:IMELOPYDEBT://执行参数(数字)
MELODY://灯光及震动控制脚本
END:IMELODY
----
BEGIN:IMELODY
VERSION:1.2
五、我们要再搞清楚一点:
IMY详解:
(iMelody Ringtone Format):这是被专门设计用于EMS中的铃声,与年由爱立信提出,并与年6月得到3GPP认可成为标准,i-Melody铃声基于文本的方式标志音调,它的标准化工作由IrDA负责。支持EMS的爱立信以及现在的索尼爱立信手机型号多采用i-Melody铃声格式。
IMY是一种手机的铃声格式。它是 年由爱立信提出的一种音频...IMY 是中国移动规定的通用彩信文件格式之一,但是支持这一文件格式自播放和铃声的手机并不多。
IMY是属于单音格式(非和弦)
直接可以在手机上编写音符
再谈谈MTK为什么会出现这个漏洞,早在MTK 年代是没有此漏洞的,这也是有些老款的山寨机,对此类短信免疫的原因 !
到了 MTK年代 还记得当时山寨吹出的新功能 闪信 就是发一条短信伴随着屏幕和键盘闪,可以闪出很多 莫尔斯电码 当时看看挺个性后来可能厂商不宣传,加上大家觉得此功能鸡肋,也不再提它了,而"强大"的MTK却保留了次功能,以致漏洞的产生!
下面我独家提供下imy 的编写方式以及代码:
经过自己这两天的摸索,有些心得,奉献给大家:
(一)IMY基本格式解析
##########################
BEGIN:IMELODY
VERSION:<version>
FORMAT:<format>
[NAME:<ring_name>
[COMPOSER:<composer_name>]
[BEAT:<beat>]
[STYLE:<style>]
[VOLUME:<volume>]
MELODY:<melody>
END:IMELODY5
###########################
注:[]中为可选项 ;<>中为变量 ;两排#号间为要存储为*.imy文件中的内容
变量详解
(1)<version>:版本号。唯一值1.2
(2)<format>:格式编号。取值CLASS1.0|CLASS2.0(不了解后者是否被T支持,一般填CLASS1.0
(3)<ring_name>:ASCII字符,铃声名.
(4)<composer_name>:作者名
(5)<beat>:节奏。取值从到bpm(拍/分钟),越大节奏越快,缺省 (6)<style>:风格。取值为S0|S1|S2
; ; ; ; S0:普通。每音符间有暂停,音符与暂停时间比为:1
; ; ; ; S1:持续。每音符间无暂停
; ; ; ; S2:断奏。音符与暂停时间比为1:1
(7)<volume>:音量。取值V0到V。V0为静音,缺省V7
(8)<melody>:旋律字符串
具体格式:{ <silence>|<note>|<led>|<vibe>|<backlight>|<repeat>|<volume>}
<silence>:休止符。r<duration>[<duration-specifier>]
<duration>:"0" | "1" | "2" | "3" | "4" | "5",分别为全音符、半音符、1/4音符...1/音符
<duration-specifier>:"." | ":" | “;” ;延时符,1.5倍、1.倍与2/3倍)
<led>:led特效。"ledoff" | "ledon"
<vibe>:振动特效。"vibeon" | "vibeoff"
<backlight>:背景灯特效。"backon" | "backoff"
<repeat>:重复特效。"("+<melody>+"@n)" ; ; ;n取值0到无穷大
<note>:音符。格式为[<octave-prefix>]<basic-ess-iss-note><duration>[<duration-specifier>],
<octave-prefix>:音阶。取值"*0" | "*1" | … | "*8" (a=Hz) | (a=Hz) | … | (a= Hz)
缺省"*4",代表标准音(小字一组a音为Hz)
特别提示:用的编辑器录入时只有"*4"到"*8",
<basic-ess-iss-note>:具体唱名。
<basic-note>取值"c" | "d" | "e" | "f" | "g" | "a" | "b"(自然音)
<ess-note>取值"&d" | "&e" | "&g" | "&a" | "&b"(降半音)
<iss-note>取值"#c" | "#d" | "#f" | "#g" | "#a"(升半音) (二)手工录入方法:
大家是不是已经看晕了?反正我自己已经快晕了。OK,进入正题,让我们用随机带的一首Funky来做例子
从手机中导出的funky.imy如下:
BEGIN:IMELODY
VERSION:1.
FORMAT:CLASS1.0
STYLE:S0`
VOLUME:V2
MELODY:vibeong2vibeoffbackoff*5d3g3*5&d3g2*5c2.backonledong2backoffledoff&b2backonledong2ledoffbackoffvibeonr2vibeoff*5d3g3*5&d3g2&b2.g2f2g2vibeonr2vibeoff*5c3*5&d3&b3g2&b2.backong2backofff2backong2backoffvibeonr2vibeoff*5c3*5&d3&b3g2&b2.r2r2backond4backoffr4backond4backoffr END:IMELODY
取"vibeong2vibeoffbackoff*5d3"来举例说明录入方法进入“编辑器”:
(1)按OPTION键(YES下面的)-2-6,插入"vibeon"
(2)"g2"前面无"*4",为缺省音阶,按5,插入标准音阶的1/4音符g音
(3)按键OPTION-2-5,插入"vibeoff"
(4)按键OPTION-2-3,插入"backoff"
(5)按键2-0-8,插入高八度的1/8音符d音(*5意味着高八度,按0提升;d后面的3是指1/8音符,按8减少持续时间就将原来的1/4音符减为1/8音符,其后节拍有变化记得用8和9调整!)
再取接近最后的"&b2.r2r2backond4backoffr4"说明:
(1)按键7-#-OPTION-6-“四分音符”-YES,插入"&b2.",降半度的1/4音符b音,带附点延长(原长的1.5倍)
(2)按键*,插入1/4拍休止符"r2"
(3)同(2)
(4)按键OPTION-2-4,插入"backon"
(5)按键2-8-8,插入1/音符"d4"(用8键调两次从原1/4拍得到1/拍)
(6)按键OPTION-2-3,插入"backoff"
(7)按键*,插入1/休止符"r4"(为何不用8和9调整呢?注意第(5)步已经设置成了1/拍!
例二:HeartBeat
BEGIN:IMELODY
VERSION:1.2
FORMAT:CLASS1.0
BEAT:
MELODY:(ledonvibeonvibeonvibeonvibeonvibeonledoffvibeoffr5ledonvibeonvibeonvibeonledoffvibeoffr2@)* t& j' j }% @5 m6 t$ Q
END:IMELODY
输入序列不全列上,只取关键处:
(1)按键OPTION-3-输入,将节奏改为
(2)按键OPTION-2-7,设置重复段起点
......(中间过程略,到"@"之前)
(3)按键OPTION-2-8-9(长按9直到右上角数字变成),设置重复段结尾,并设置重复次数为次(不按9而直接按一次8会变成无穷大的标志)
大功告成!原理与基本操作已经告诉大家,享受自己手工慢慢编曲的快乐(or痛苦)吧!
不过若真有人能用T的编辑器手工录入那没有长度限制的imy铃声,我由衷地佩服他的毅力.有些短小的imy效果铃声,到不妨练练手。
篇后语:今天夜班,闲来无事,遂成此文。多从IMY的英文版基本格式说明入手,对照导出的IMY文件,多番试验,终有所成,不敢独享。鉴于对作曲完全不了解,以及对英文理解可能有偏差,难免有错漏之处,欢迎指正,共同探讨。
另外发几个黑屏短信和震动短信的代码以及解密:(请勿滥用,否则后果自负))
例
BEGIN:IMELODY
VERSION:1.2
FORMAT:CLASS1.0
BEAT:
MELODY:(ledoffledonbackoffbackonvibeon@0)
END:IMELODY
根据IMY格式语法,这条短信就是个闪光震动代码:
(ledoff ledon , backoff backon , vibeon , @0)
[开关LED(闪动),开关背景灯(闪动),开震动],重复无
求C语言小游戏源程序
我的楼主可以自己玩一下
试试吧
#define N
#include <graphics.h>
#include <stdlib.h>
#include <dos.h>
#define LEFT 0x4b
#define RIGHT 0x4d
#define DOWN 0x
#define UP 0x
#define ESC 0xb
int i,key;
int score=0;/*得分*/
int gamespeed=;/*游戏速度自己调整*/
struct Food
{
int x;/*食物的横坐标*/
int y;/*食物的纵坐标*/
int yes;/*判断是否要出现食物的变量*/
}food;/*食物的结构体*/
struct Snake
{
int x[N];
int y[N];
int node;/*蛇的节数*/
int direction;/*蛇移动方向*/
int life;/* 蛇的生命,0活着,1死亡*/
}snake;
void Init(void);/*图形驱动*/
void Close(void);/*图形结束*/
void DrawK(void);/*开始画面*/
void GameOver(void);/*结束游戏*/
void GamePlay(void);/*玩游戏具体过程*/
void PrScore(void);/*输出成绩*/
/*主函数*/
void main(void)
{
Init();/*图形驱动*/
DrawK();/*开始画面*/
GamePlay();/*玩游戏具体过程*/
Close();/*图形结束*/
}
/*图形驱动*/
void Init(void)
{
int gd=DETECT,gm;
initgraph(&gd,&gm,"c:\\tc");
cleardevice();
}
/*开始画面,左上角坐标为(,),右下角坐标为(,)的围墙*/
void DrawK(void)
{
/*setbkcolor(LIGHTGREEN);*/
setcolor();
setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/
for(i=;i<=;i+=)/*画围墙*/
{
rectangle(i,,i+,); /*上边*/
rectangle(i,,i+,);/*下边*/
}
for(i=;i<=;i+=)
{
rectangle(,i,,i+); /*左边*/
rectangle(,i,,i+);/*右边*/
}
}
/*玩游戏具体过程*/
void GamePlay(void)
{
randomize();/*随机数发生器*/
food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/
snake.life=0;/*活着*/
snake.direction=1;/*方向往右*/
snake.x[0]=;snake.y[0]=;/*蛇头*/
snake.x[1]=;snake.y[1]=;
snake.node=2;/*节数*/
PrScore();/*输出得分*/
while(1)/*可以重复玩游戏,压ESC键结束*/
{
while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/
{
if(food.yes==1)/*需要出现新食物*/
{
food.x=rand()%+;
food.y=rand()%+;
while(food.x%!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/
food.x++;
while(food.y%!=0)
food.y++;
food.yes=0;/*画面上有食物了*/
}
if(food.yes==0)/*画面上有食物了就要显示*/
{
setcolor(GREEN);
rectangle(food.x,food.y,food.x+,food.y-);
}
for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/
{
snake.x[i]=snake.x[i-1];
snake.y[i]=snake.y[i-1];
}
/*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/
switch(snake.direction)
{
case 1:snake.x[0]+=;break;
case 2: snake.x[0]-=;break;
case 3: snake.y[0]-=;break;
case 4: snake.y[0]+=;break;
}
for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/
{
if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])
{
GameOver();/*显示失败*/
snake.life=1;
break;
}
}
if(snake.x[0]<||snake.x[0]>||snake.y[0]<||
snake.y[0]>)/*蛇是否撞到墙壁*/
{
GameOver();/*本次游戏结束*/
snake.life=1; /*蛇死*/
}
if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/
break;
if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/
{
setcolor(0);/*把画面上的食物东西去掉*/
rectangle(food.x,food.y,food.x+,food.y-);
snake.x[snake.node]=-;snake.y[snake.node]=-;
/*新的一节先放在看不见的位置,下次循环就取前一节的位置*/
snake.node++;/*蛇的身体长一节*/
food.yes=1;/*画面上需要出现新的食物*/
score+=;
PrScore();/*输出新得分*/
}
setcolor(4);/*画出蛇*/
for(i=0;i<snake.node;i++)
rectangle(snake.x[i],snake.y[i],snake.x[i]+,
snake.y[i]-);
delay(gamespeed);
setcolor(0);/*用黑色去除蛇的的最后一节*/
rectangle(snake.x[snake.node-1],snake.y[snake.node-1],
snake.x[snake.node-1]+,snake.y[snake.node-1]-);
} /*endwhile(!kbhit)*/
if(snake.life==1)/*如果蛇死就跳出循环*/
break;
key=bioskey(0);/*接收按键*/
if(key==ESC)/*按ESC键退出*/
break;
else
if(key==UP&&snake.direction!=4)
/*判断是否往相反的方向移动*/
snake.direction=3;
else
if(key==RIGHT&&snake.direction!=2)
snake.direction=1;
else
if(key==LEFT&&snake.direction!=1)
snake.direction=2;
else
if(key==DOWN&&snake.direction!=3)
snake.direction=4;
}/*endwhile(1)*/
}
/*游戏结束*/
void GameOver(void)
{
cleardevice();
PrScore();
setcolor(RED);
settextstyle(0,0,4);
outtextxy(,,"GAME OVER");
getch();
}
/*输出成绩*/
void PrScore(void)
{
char str[];
setfillstyle(SOLID_FILL,YELLOW);
bar(,,,);
setcolor(6);
settextstyle(0,0,2);
sprintf(str,"score:%d",score);
outtextxy(,,str);
}
/*图形结束*/
void Close(void)
{
getch();
closegraph();
}
c++表白代码烟花
c++表白代码烟花是什么呢?不知道的小伙伴来看看小编今天的分享吧!
烟花源代码:
#include graphics.h
#include conio.h
#include math.h
#include time.h
#include stdio.h
#include Mmsystem.h
#pragma comment ( lib, Winmm.lib )
/***** 宏定义区