[Powered by Google Translate] [周5] 戴维·J·马兰,哈佛大学] 这是CS50。[CS50.TV] [女人]他在说谎的是什么,我不知道。 [文]因此,我们知道些什么? [女人] 9时15分,雷Santoya是在ATM。 [文]因此,问题是,什么是他做的9:16? [女人]拍摄9毫米的东西。 也许他看到了狙击手。 [文]他与他共事。 [女人]等待。回到一个。 [文]你看到了什么? [♫悬疑音乐♫] [女人]把他的脸。全屏。 [文]他的眼镜。 >>共有的一种体现。 [♫悬疑音乐♫] [文]这是在Nuevita的棒球队。这是他们的标志。 [女人]他在说给谁穿的那件夹克。 [大卫·马兰]所以,这是CS50 5周,而今天我们为你毁了一个位电视和电影。 所以,每当你看像这样的在这里表演, 警察说:“你能不能清理一下?”或“增强” 有没有提高在现实世界中。 事实上,你真正得到的是这样一个小东西。 我把从页面的员工照片之一。 这是一个被称为Photoshop的。这是1 2 Bowdens 1 3 Bowdens实际上,今天,是因为我们有夫人波顿这里,Rob和保罗。 但这里是抢在屏幕上,如果我们放大上,闪闪发光,他总是有他的眼睛, 你看到的就是你所看到的就是你得到的。 这是“增强”,因此“CSI”有点不对劲。 还有另外一个片段,如果我们可以选择“CSI”只是一点点的时间。 这是一个很好的短语,从今以后,如果你想说出 完善的技术的时候,真的与你的朋友,你是说绝对没有。 [文]几个星期以来,我一直在调查的马车夫的杀手谋杀 具有一定的病态的迷恋。 [女人#1]这是实时的。 [女人]我使用Visual Basic创建一个GUI界面,看看我是否能跟踪一个IP地址。 [马兰]音频不同步一旁,创建一个GUI界面,使用Visual Basic 跟踪一个IP地址是完全荒谬的。 这些日子里,你将不能使用Visual Basic, 有没有需要一个图形用户界面,IP地址是一个技术上准确的术语。 因此,保持一个眼睛,对于这些,我的最爱之一: 这其中的多了几分神秘的,因为你需要知道不同的语言。 有一种语言叫Objective-C中,这是一个C的超集 这意味着它的C加上一些额外的功能,其中包括面向对象的编程。 这是语言,苹果已经为iOS编程推广。 因此,这里是一个片段从一个完全不同的节目,从“数字” 其实,如果你仔细看你的TiVo和暂停在适当的时候, 你会看到,他们想要的东西是不太所描述的是什么。 让我尝试不同的音频连接器,看看如果我们不能 保持音频的同步时间。 我给你的“数字”。 [文#1]这是一个32位的IPv4地址。 [文2]的IP地址,这是互联网。 >>专用网络。这是梅艳芳的专用网络。 [马兰]好吧。这是Objective-C,这是一些孩子的着色方案, 你或许可以推断出变量的名称。 这样,那么,“数字”。所以我们今天和本周介绍 取证和背景的问题,因此世界上的一点点。 今天将是一个简短的演讲,因为在这里有一个特殊的事件 之后,我们将采取偷看,和逗学生和家长的一致好评今天 一些的东西,是在地平线上。 其中,截至周一,你将有一些更多的同学。 EDX,哈佛和MITS新的在线主动开放课件 多,正在启动(星期一)在哈佛的校园。 这意味着前来周一,你将有 - 如最近的一次统计, 86,000额外的同学也将会跟随着CS50的演讲 和部分演练和习题集。 作为这项工作的一部分,你会成为会员的首届类 CS50和现在CS50x。 作为其中的一部分,现在,意识到,会有一些不相上下以及。 要为此做好准备,对于数量庞大的学生, 可以肯定地说,即使我们有108个转录因子和CA, 不太最好的学生/教师比例后,我们打80000其他学生。 因此,我们不会被分级这么多的问题,手动设置。 所以,本周推出的习题集将是CS50检查, 这将是一个命令行实用程序在设备 一次,你会得到你以后更新本周末, ,你就可以运行一个命令,检查50 在您自身的pset中,你会得到一些反馈,为您的程序是否 正确的或不正确的,根据我们所提供的各种设计规范。 因此,更多的问题设定的规范和 CS50x同学们将利用这一点。 所以,问题设置4个是所有约取证。 这件作品的灵感来自一些真实的东西, 由此,当我在读研究生,我实习一段时间, 米德尔塞克斯郡的地区检察官办公室从事法医工作 他们的领导取证调查,这为 ,我想我提到的几个星期过去,是质量国家警察或其他 会来的,他们会脱落的东西,如硬盘驱动器和光盘和软盘 等,然后取证办公室的目标是,以确定是否 有或没有某种形式的证据。 这是特别调查组,所以它是白领犯罪, 更令人不安的是排序的犯罪, 什么涉及某种数字媒体;原来,没有那么多的人 写一封电子邮件说:“我做到了。” 所以,很多时候,这些取证搜索没有打开所有的东西,水果, 但有时人们会写这样的邮件。 所以有时的努力得到了回报。 但是,得出了这个法医pset中,我们将介绍在pset中4位的图形。 所以,你可能把这些东西是理所当然的,JPEG格式,GIF和像这些天, 但如果你真的仔细想想,图像,就像罗布的脸, 可以建模为一个序列的点,或像素。 现在,在罗布的脸的情况下,有各种颜色, 我们开始看到的各个点,otherwide称为像素, 一旦我们开始放大。 但是,如果我们简化了这个世界变得,只是说,这里是Rob 在黑色和白色,代表黑色和白色,我们可以只使用二进制文件。 如果我们要使用二进制的1或0,我们可以表达这种相同的图像 Rob的笑脸这种模式位:11000011表示 白,白,黑,黑,黑,黑,白白。 因此,这不是一个巨大的飞跃,然后,开始谈论精美图片。 的东西,你会看到在Facebook或用数码相机, 但肯定的是,当涉及到颜色,你需要更多的比特。 在世界上的照片相当普遍的是使用1位颜色, 因为这建议,但24位色,你实际上得到数百万种颜色。 因此,作为的情况下,当我们放大罗布的眼睛上, 这是任何数以百万计的不同颜色的可能性。 因此,我们就为大家介绍这方面的问题集4以及在演练中, 这将是今天下午3:30,而不是平常的下午2时30分,因为上周五的演讲在这里。 但视频是在线的,像往常一样,明天。 我们还将为您介绍另一种文件格式。 因此,这是故意为了看起来吓人, 但是,这仅仅是一些文件的C结构。 事实证明,微软,几年前,捧红了这种格式, 被称为位图文件格式,BMP,这是一个超级简单的, 丰富多彩的图形文件格式,使用相当长的一段时间 有时仍然在桌面上的壁纸。 如果你觉得回到了Windows XP和绵延的群山和蔚蓝的天空, 这是典型的一个BMP位图图像,位图 是我们的乐趣,因为他们有了更多的复杂性。 这不是一件简单的事情,因为这格的0和1的; 代替,你必须像一个头在一个文件的开始的东西。 所以,换句话说,里面的。bmp文件是0和1的一大堆, 但有一些额外的0和1的在那里。 而事实证明,我们可能已经多年理所当然的, doc或xls或。MP3或MP4的文件格式,如, 任何你熟悉的文件格式。 那么,是什么它甚至意味着是一个文件格式? 因为在一天结束的时候,我们使用所有这些文件都只是0和1的 也许那些0和1的代表,乙,丙,通过ASCII或等, 但通过一天结束的时候,它只是0和1。 因此,人类只是偶尔决定发明一种新的文件格式 他们规范的位模式,实际上的意思。 在这种情况下,这里的人谁设计的位图文件格式 说,在第一个字节中的位图文件,并标示为偏移0,在那里, 将是一些神秘命名的变量称为bfType, 这只是代表了位图文件的类型,这是什么类型的位图文件。 你可以推断出,或许,从第二排,偏移量为2,第2字节数 有图案的0和1组成的,代表什么吗? 事物的大小,它从那里。 因此,问题集4中,你会走过一些事情。 我们不会关心所有的人,但是请注意,它开始变得有趣 周围线或54字节,rgbtBlue,绿色和红色。 如果你听说过的缩写,RGB,红,绿,蓝,这是一个参考。 因为事实证明,你可以画的彩虹的所有颜色 与红色,蓝色和绿色的某种组合。 而且,事实上,在房间里的父母可能还记得最早的投影机。 这些天,你只看到1个明亮的光出来的一个镜头。 但是,早在一天,你有红色的镜片,蓝色镜片,绿色镜片 和他们一起旨在在屏幕上,并形成了丰富多彩的画面。 经常中学和高中有那些镜头 不断稍微歪斜,所以你看到双重或三重影像, 但他的想法。你有红色,绿色和蓝色光画一幅画。 在电脑上使用相同的原则。 因此,当中的挑战,那么,你在问题设置4 将要几件事情,一个是调整图像的大小。 要采取的图案中的0和1, 找出结构中的这样的块0和1的代表, 然后找出如何复制像素的红色,蓝色,果岭 内,这样当最初的图片看起来是这样的,可能是这样的,而不是之后。 在其他的挑战,也将是你会交由 法医的形象,一个实际的文件从数码相机 ,相机,曾几何时,一大堆的照片。 问题是,我们不小心删除或有图像损坏,不知何故。 数码相机,不好的事情发生,所以我们很快就复制了所有的0和1的 关闭该卡给你,救了他们一大的文件,然后我们会交给你 在问题设置,让您可以写一个程序在C恢复 所有这些JPEG文件,最好。 而事实证明,JPEG文件,即使它们是有点复杂的文件格式, 他们要复杂得多,这笑脸。 事实证明,每一个JPEG相同的模式0和1的开始。 因此,使用一个while循环或循环或类似的, 你可以遍历所有的0和1这法医图像 每次你看到的问题集的规范中定义的特殊模式, 你可以假设,“哦,这里是具有非常高的概率, 开始的JPEG,只要你找到相同的模式, 一定数目的字节或千字节或兆字节后, 你可以假设,“哦!这是第二个JPEG的照片后,我把第一个。 让我停止阅读,第一个文件,开始写这个新的。“ 你的程序的pset 4的输出将是多达50个JPEG文件。 而且,如果它不是50 JPEG文件,你有一点的循环。 如果你有无限多的JPEG文件,你有一个无限循环。 这样一来,也将是一个相当普遍的情况。 这是在地平线上。 测验0,在我们背后。实现的,按我的电子邮件,总是有乡亲 谁是既高兴,排序中性,和伤心周围测验0时。 请你拿出来给我,头转录因子,Zamyla,你自己的TF 的CA,你知道,如果你想讨论如何去。 因此,要在这里留下深刻印象的父母在房间里, 是CS50库?干得好。 的CS50库?是吗? [学生回答,不知所云] >>好,好。所以这是一个预先写好的代码集,我们的工作人员,写, 我们提供给你,提供一些常用的功能。 的东西,如给我一个字符串,让我一个int,此处列出的所有的功能。 从现在起,我们开始真正把这些训练车轮。 因此,我们要开始你带走一个“字符串”, 其中,召回,只是一个代名词什么实际的数据类型吗?的char *。 因此,对于家长,这很可能是 - 这是很好的,这样的char *,我们将开始看到 在屏幕上,更因为我们从我们的词汇中删除“字符串”, 至少当涉及到实际编写代码。 同样,我们将停止使用其中的一些功能多, 因为我们的计划是要变得更加复杂 而不是仅仅写一个提示,闪烁坐在那里, 等待用户输入一些东西英寸 你会得到你的输入来自其他地方。 例如,你会得到他们的本地硬盘驱动器上的一系列位。 相反,你会得到他们在未来的网络连接,一些网站的某个地方。 因此,让我们剥开这层第一次,并拉起CS50家电 这称为CS50.h的文件,你已经尖锐包括好几个星期。 但是,让我们看到这里面有什么。 因此,顶蓝色的文件仅仅是一大堆的意见, 保修信息和许可。这是一个共同的范式 软件,因为很多软件,这些天是所谓的“开放源码” 这意味着有人已经写好的代码 和自由,而不是仅仅运行和使用, 但实际上读取和改变,并融入自己的工作。 所以,这就是你一直在使用,开放源代码软件, 尽管在一个非常小的形式。 不过,如果我向下滚动过去的意见,我们将开始看到一些比较熟悉的东西。 因此,注意到这里的顶部,CS50.h文件包括一大堆的头文件。 现在,这些我们都没有见过,但一个是 熟悉的,这些我们看到,尽管是短暂的,迄今? 是的,标准库。 stdlib.h中的malloc, 所以一旦我们开始谈论动态内存分配, 我们会回来下周开始,包括该文件。 事实证明,布尔和真假实际上并不存在,在C,本身, 除非你有这个文件在这里。 因此,我们有好几个星期,得到了包括标准bool.h 这样,您可以使用这个概念的一个布尔值,true或false。 没有这一点,你就必须假的排序,并使用int 只是任意假设0是假的,1是真实的。 现在,如果我们继续向下滚动,在这里我们定义一个字符串。 事实证明,正如我们之前所说的,,*其实并不重要。 你甚至可以有空间的限制。 这学期,我们一直在推动它,因为这明确指出,*与类型。 但要意识到,就像常见的,如果没有一点更常见的,是把它放在那里 但在功能上是一样的东西。 但是现在,如果我们读到进一步下降,让我们来看看在说,调用getInt, 因为我们使用的是,也许,先天下之忧这个学期。 这里是调用getInt。这是什么? 这是原型。所以很多时候,我们已经把原型在我们的顶部。c文件, 但你也可以把原型的头文件,。h文件, 像这样的在这里,所以,当你写的一些功能 你希望其他人能够使用,这是完全相同的情况下,的CS50库, 你不仅实现你的功能的东西像CS50.c, 也把原型而不是在该文件的顶部,但在一个头文件的顶部, 然后,头文件是什么样的朋友和同事,包括, 用锋利的,包括在自己的代码。 因此,所有这时候你已经包括所有这些原型 有效地在文件的开头,但这种尖锐的方式,包括机制 到,从本质上说,这个文件复制和粘贴到您自己的。 现在,这里是一些比较详细的文档。 我们几乎是理所当然的调用getInt得到一个int, 但事实证明,有一些角落的情况下,对不对? 如果用户键入的数字太大了吗? 一个三次方,就不能装进一个int? 什么是预期的行为吗?那么,理想的情况下,这是可预见的。 因此,在这种情况下,如果你真正阅读印刷精美, 你会看到,如果该行不能被读取,则返回INT_MAX。 我们从来没有提到这一点,但其资本额的基础上, 它是什么,可能吗? 这是一个常数,所以它的一些特殊常量,可能宣布 了更高的文件中的这些头文件之一, INT_MAX可能是类似的东西,大约2亿美元。 的想法是,因为我们需要以某种方式表明的东西出了问题, 是的,我们有我们所掌握的4十亿的数字, 负2亿美元至2亿美元,给予或采取。 那么,什么是常见的编程是你偷这些数字。 也许0,也许2十亿,也许负2亿美元。 所以你用一个可能的值,这样就可以提交到世界 ,如果出现错误,我会回到这个超级大的价值。 但你不希望用户输入诸如“2,3,4神秘的东西......” 非常大的数字,在那里你概括,而不是为一个常数。 所以,真的,如果你是肛门过去的几个星期中, 任何时候,你调用调用getInt,你应该已经检查的,如果条件。 做了用户在INT_MAX类型,或者更具体地说, 调用getInt返回INT_MAX?因为如果它这样做, 实际上意味着他们没有输入,在这种情况下,出现了错误。 因此,这是通常被称为一个“哨兵”的价值,这只是意味着什么。 好了,现在让我们来打开的。c文件。 C文件已经存在了一段时间的家电, ,事实上,该设备具有预编译为你 到那个东西我们称之为“目标代码” 但它只是对你重要,那是因为系统知道, 在这种情况下,它的位置,该设备。 但是,让我们现在向下滚动到调用getInt,看看如何调用getInt一直在这么长的时间。 所以,在这里,我们从之前也有类似的评论。 让我放大的代码部分, 我们调用getInt如下。 它没有输入和返回一个int,而(真),所以我们有一个故意的无限循环 但是,据推测,我们将打破这个不知何故,或返回在此。 因此,让我们来看看它是如何工作的。那么,我们似乎可以使用GetString 在这第一行内循环,166。 现在,这是很好的做法,因为在什么样的情况下, 可能的GetString返回这个特殊的关键字,NULL吗? 如果出现错误。什么可能出问题,当你调用类似的GetString? 是吗? [学生回答,不知所云] >>呀。因此,也许malloc失败。 引擎盖下方的GetString调用malloc, 它分配内存,这使得计算机存储 所有的字符,进入键盘的用户类型。 假设用户有一大堆的空闲时间 和类型化的,例如,超过2十亿字符。 甚至有更多的字符比计算机RAM。 是,GetString能够以表​​示对你, 即使这是一个超级,超级罕见的角落的情况。 它以某种方式来处理这个问题,所以GetString的, 如果我们回过头来阅读其说明文件,不,其实,返回NULL。 现在,如果GetString的失败,返回NULL,调用getInt是要失败的 返回INT_MAX,就像一个哨兵。 这些都只是人的约定。只有这样,你会知道这是 是通过阅读文档。 因此,让我们向下滚动到的诠释其实是GotInt的地方。 所以,如果我向下滚动位,在170行,我们有意见,以上这些线路。 因此,我们宣布,在172,一个int n和一个字符c,那么这个新功能 你们中的一些偶然发现之前,但sscanf的。 这代表字符串扫描f。 换句话说,给我一个字符串,我将扫描件信息感兴趣。 那么,是什么意思呢?好吧,假设我在键盘上输入,从字面上看,1 2 3, 并按下回车键。 1 2 3时,由GetString返回的数据类型是什么? 这显然​​是一个字符串,对不对?我有一个字符串,所以1 2 3是真的“1 2 3” \ 0在它的结束。这不是一个整数。 这不是一个数字。它看起来像一个数字,但它实际上不是。 那么,是什么调用getInt有什么关系?它具有从左向右扫描该字符串, 1 2 3 \ 0,并以某种方式将其转换为一个实际的整数。 现在,你可以找出如何做到这一点。 如果你觉得回到了pset中2,你大概有一点点舒适 与凯撒的vigenere,这样你就可以遍历字符串, 你可以将字符转换成整数与挑。这是一个大量的工作。 sscanf的,做一个这样的函数,你为什么不叫? 因此,sscanf的预计参数,在这种情况下,所谓的线,这是一个字符串。 然后,您可以指定,在引号中,非常类似于printf, 在此字符串你希望看到什么? 我在这里说的是什么,我希望看到一个十进制数,也许一个字符。 我们会看到为什么是这样的情况下,在短短的时刻。 事实证明,这个符号是回忆的东西 我们开始谈论了一个多星期前。 什么是&N&C为我们做吗? [学生回答,不知所云] >>呀。它给我的地址n和c的地址。 那么,为什么那么重要吗?嗯,你知道,在C函数 你总是可以返回一个值或没有价值。 您可以返回一个int,一个字符串,一个浮子,一个字符,不管。 或者你也可以返回void,但你只能返回1最大限度。 但在这里我们要sscanf的我,也许返回一个int,一个十进制数, 和一个字符,在某一时刻,我会解释为什么字符。 因此,您可以有效地希望F返回两件事情,这是不可能的C. 所以,你可以解决的,通过在2个地址, 因为只要你交给一个功能,2个地址,该功能可以与他们做吗? 它可以写入到这些地址。您可以使用*操作和“走出去”,每个地址。 这是这个后门的机制,但很常见的改变变量的值 在超过仅有1的地方,在这种情况下,2。 现在,请注意我检查==比1,然后返回n如果这样做,其实,计算结果为true。 所以,这是怎么回事呢?那么,在技术上,我们真的要发生在调用getInt是这样的。 我们要分析,可以这么说,我们要读取的字符串 “1 2 3”,如果它看起来像有一些有, 我们告诉sscanf的做的就是把这个数字,1 2 3,在我这个变量n。 那么,为什么我有这样的好了吗? 也说,sscanf的,你也可能会得到一个字符,在这里的作用是什么。 学生来说,不知所云] >> - 一个小数点工作。 让我们认为,想了一会儿。还有什么呢? [学生,不知所云] >>因此,良好的思想,它可能是NULL字符。 它实际上不是,在这种情况下。是吗? [学生,不知所云] >> ASCII。或者,让我进一步概括。 %c有错误检查。 我们不希望有字符数后, 但让我做的是以下几点: 事实证明,sscanf的,除了存储在n和c的值,在这个例子中在这里, 什么也没有返回的变量值英寸 所以,如果你只输入1 2 3,%d是要匹配 只有n被存储像1 2 3的值,都不会在c; C保持一个垃圾值,可以这么说。 垃圾,因为它从来没有被初始化为一定的价值。 因此,在这种情况下,sscanf的返回1,因为我填充这些指针之一, 在这种情况下,太棒了。我有一个int,所以我释放线释放内存 其实GetString的分配,然后我返回n。 否则,如果你有没有想过,重试语句,就是这里。 如果相反,I型1 2 3富, 只是一些随机序列的文本,,sscanf的是要看到, 哦,数量,哦,数量,哦,数量,噢 - F。 它打算把1 2 3在n。 这将放置在f中的c,然后返回2。 因此,我们有,只是用scanf函数的行为的基本定义, 一个非常简单的方法 - 乍一看,复杂的,但在一天结束的时候, 机制相当简单的说,是有一个int,如果有的话,那件事,我发现吗? 这里的空白是故意的。如果你读的文档sscanf的, 它会告诉你,如果你有一块空白的开始或结束, sscanf的也将允许用户,无论出于何种原因,打空格键1 2 3,,这将是合法的。 只是因为他们打的开头或结尾的空格键,它不会在用户嚷嚷, 这只是一个小更方便用户使用。 有任何疑问的话,就GetInts?是吗? [学生提问,不知所云] >>很好的问题。什么,如果你刚才输入的一个字符,如f和命中输入 没有输入1 2 3,你怎么看这行代码的行为,然后呢? ,所以sscanf的覆盖太多,因为在这种情况下, 它不会以填补N或C,这是怎么回事,而不是返回0。 在这种情况下,我也赶上那种情况下,我想是因为预期值1。 我只希望,只有1个东西来填补。这个问题问得好。其他人吗? 好吧,让我们不要去所有的功能在这里, 但,这似乎是,也许,余下权益 GetString的,因为它把GetFloat,调用getInt GetDouble,GetLongLong所有平底船了很多的功能,GetString的,。 因此,让我们来看看他是如何在这里实现。 这一个看起来有点复杂,但它使用相同的基本原理 我们开始谈论上周。因此,在GetString时, 它没有参数,在这里,每虚空 和它返回一个字符串,所以我声明了一个字符串缓冲。 我真的不知道那是什么要用于还,但我们会看到。 看起来像容量,默认情况下,0不太清楚这是怎么回事。 不知道N的将要用于还。 但现在变得更有趣一些,所以在243, 我们声明了一个int C,这是一个愚蠢的细节。 char是8位,8位可以存储多少不同的值吗? 256。现在的问题是,如果你想有256个不同的ASCII字符, 有,如果你想回来,这是不是记住。 但是,如果你觉得回到了那个大的ASCII图表,我们有几个星期前, 有,在这种情况下,128个或256个ASCII字符。 我们使用的所有模式0和1的。 这是一个问题,如果你想成为能够检测到一个错误。 因为如果你已经使用了256个值,为你的角色, 你真的不提前计划,因为现在你也没有办法说, “这是不是一个合法的字符,这是一些错误的信息。” 因此,世界的是,他们使用的下一个最大的价值, 像int的东西,让你有一个疯狂的数位, 32 4亿可能的值,这样你可以简单地结束了, 基本上,257,1其中有一些特殊的含义为错误。 因此,让我们来看看它是如何工作的。在246行,我有这样大的while循环 正在调用fgetc函数F含义文件,GETC,然后标准输入。 原来,这只是说:“从键盘读取输入更精确的方法。” 标准输入方式键盘,标准输出屏幕, 和标准错误,我们会看到在pset中,是指在屏幕上, 而是一种特殊的屏幕部分,因此,它不是混为一谈 与实际输出,你打算打印,但更多的是在未来。 因此fgetc函数从键盘读取一个字符,并将其存储在那里? 将它保存在c,然后检查,所以我只是在这里使用一些布尔连词, 检查它不等于\ n,所以用户按下回车键。 我们要停止在这一点上,在循环结束,我们还需要检查 特殊常量,EOF,如果你知道或猜测 - 什么是代表? 文件结尾。因此,这是一种荒谬的,因为如果我在键盘上打字, 真的没有参与这一文件, 但是,这仅仅是排序的通用术语,用来指 ,没有别的来自人类的手指。 EOF。文件结尾。 顺便说一句,如果你曾经打你的键盘,控制D 不是说你还没有,你已经打了控制C。 但是,控制D发送这个特殊的常数,称为EOF。 所以,现在我们只是有一些动态内存分配。 因此,如果n + 1>的能力,现在我将解释N。 n是目前究竟有多少字节在缓冲区中, 你目前正在建设的字符串从用户。 如果你有比你有更多的字符在缓冲区中的缓冲能力, 直观地,我们需要做的,然后被分配更多的容量。 我要掠过的算术 只注重这个功能。 你知道的malloc的是,或者至少是一般熟悉。 什么realloc的猜测。 [学生回答,不知所云] >>呀。 ,它不是很新增记忆体,它重新分配内存,例如: 如果在字符串的结尾还是有空间,该内存以使您更 比原来给你,然后你会得到额外的内存。 所以,你可以把字符串的字符背靠背背靠背。 但如果不是这样的话,因为你等太久 和一些随机得到了一屁股到内存中,但有额外的 记忆到这里,那也没关系。 realloc是要为你做所有的繁重, 移动您已经阅读因而在离这里不远的字符串, 爱不释手,然后给你一些更多的在这一点上跑道。 因此,一挥手,让我说,是做什么的GetString 是它的一个小缓冲区,也许单个字符开始, 如果在2个字符的用户类型,GetString的结束 调用realloc和说:“噢,1个字符是不够的。 给我2个字符。然后,如果你读通过的逻辑循环, 它会说,'噢,用户输入3个字符。 现在给我,而不是2 4个字符,然后给我8,然后给我16位和32位。“ 事实上,我的能力增加一倍 意味着,缓冲区不会生长缓慢。 这是怎么回事增长超级快,那可能是什么优势? 为什么我加倍的缓冲区的大小,即使该用户 可能只需要1个额外的字符从键盘吗? [学生回答,不知所云]。 >>那是什么? 没错。您不必经常增长。 而这仅仅是一个怎样的 - 你们在这里对冲你的赌注。 的想法是,你不希望调用realloc的有很多,因为它往往是缓慢的。 任何时候,你问的操作系统的内存,你很快就会看到 在未来的习题集,它往往需要一定的时间。 因此,最大限度地减少,大量的时间,即使你浪费了一些空间,往往是一件好事。 但是,如果我们在这里读通过的最后部分,GetString的, 再次,了解这里的每一行是不那么重要的今天。 但是请注意,它最终会再次调用malloc,它分配 一样多的字节,因为它需要的字符串 然后扔掉,过大的缓冲区,通过调用free 如果它确实得到了太多的时间翻了一倍。 总之,这是多么的GetString已工作时间。 它的作用是读取一个字符时,一而再,再而三 而每次需要一些额外的内存,它要求它的操作系统通过调用realloc的。 有什么问题吗?好的。 的攻击。现在,我们理解指针,或至少 越来越熟悉的指针, 让我们考虑如何在整个世界开始崩溃 如果你不太捍卫对对抗性用户, 人谁试图攻入你的系统。 谁是试图窃取您的软件绕过一些注册码 否则,他们可能有输入英寸 看一看在这个例子中,这仅仅是C代码 的底部,有一个main函数的调用函数foo, 又是什么呢传递给foo? [学生]:一个参数。 >>单参数。所以的argv [1],这意味着用户键入的第一个字 在命令行后a.out或其他程序调用。 所以foo的顶部,需要一个char *,但char *是什么? 字符串。这里没有什么新的,而该字符串是任意被称为酒吧。 在这里,字符c [12],半技术英语的排序,这条线是在做什么? 阵列 - ?字符。给我一个阵列为12个字符。 因此,我们可以称之为一个缓冲。它在技术上被称为C,但程序中的缓冲区 只是指一些空间,你可以把一些东西英寸 然后最后,memcpy的,我们还没有使用过的。 但是,你可能已经猜到它做什么。它的内存复制。 它有什么作用呢?那么,它显然复制酒吧,它的输入,转换成C, 但只有到酒吧的长度。 但有一个错误在这里。 好了,所以在技术上我们确实应该做的strlen(酒吧)x sizeof(char)的的,这是正确的。 但是,在最坏的情况下,在这里,让我们假设that's - 所以,没关系。 然后有2个错误。所以sizeof(char)的的,所有的权利,让我们使这一点更广泛。 所以现在仍然是一个错误,这是什么? [学生回答,不知所云] >>检查是为了什么?好了,我们应该检查 为NULL,因为不好的事情发生时,你的指针为NULL, 因为你可能去那里,你永远不应该为NULL 提领*操作符。 所以这是很好的,我们在做什么?在逻辑上有一个缺陷。 [学生回答,不知所云] >>因此,检查如果ARGC≥2,? 好了,所以有3这个程序中的错误。 我们不检查,如果用户实际上在什么到argv [1],良好的输入。 那么什么是第三个错误吗?是吗? [学生回答,不知所云] >>好。 所以,我们检查了一个情景。隐式检查,请不要复制更多的内存 比超过该长度的酒吧。 因此,如果字符串用户输入的长度为10个字符, 这是说,“仅复制10个字符。 这没关系,但如果用户在提示符下键入一个字 像一个20个字符的字,这是,,说复制20个字符,从酒吧到什么? C,否则被称为我们的缓冲区,这意味着你只是写数据 8个字节,你没有自己的位置, 你并不拥有它们在这个意义上,你永远不分配。 因此,这是一般被称为缓冲区溢出攻击, 或缓冲区溢出攻击,和它的攻击在这个意义上,如果用户 或调用你的函数的程序是这样做的恶意, 到底发生了什么,未来可能会相当糟糕。 让我们来看看这张图片在这里。 此图片代表你的内存堆栈。 回想一下,每次你调用一个函数, 你这个小帧在堆栈上,然后再然后另一个。 到目前为止,我们已经只是一种抽象为矩形 要么有在黑板上,或在屏幕上这里。 但是,如果我们这些矩形中的一个放大, 当你调用一个函数foo,它的出现,更重要的是在栈上 该框架和该矩形内 比是x和y,a和b,就像我们谈论交换。 事实证明,有一些较低层次的细节, 在他们返回地址。 因此,原来当主调用foo,主要有告知富 主要是在计算机的内存中的地址。 因为如果不这样,尽快为foo执行,在这种情况下,这里, 一旦你达到这种紧密的大括号结束时的foo, 如何赫克富不知道程序的控制,应该去吗? 事实证明,这个问题的答案是在这里,红色的矩形。 这是一个指针,它是电脑存储,暂时的, 所谓的堆叠上的主地址,以便尽快为foo执行完成, 电脑知道在哪里和什么线主要回去。 保存的帧指针与此类似。 CHAR *酒吧代表着什么? 好了,现在这个蓝色的部分是foo的框架,是吧? 好了,所以酒吧是参数的函数foo。 所以现在我们又回到了熟悉的画面。 还有更多的东西,并在屏幕上的干扰 但这种淡蓝色的部分是什么,我们已经画在黑板上的东西一样交换。 这是框架为foo和唯一的,现在是酒吧, 这是此参数。 还有什么应该是在堆栈中,根据此代码在这里? 字符c [12]。因此,我们也应该看到12广场的内存, 分配给一个变​​量名为c。 而事实上,我们也有在屏幕上。 最顶端的是c [0],然后这张图的作者 没有理会绘制所有的平方,但确实有12有 因为,如果你看一下在右下角,C [11],如果算上从0开始,是12个这样的字节。 但这里有一个问题:在哪个方向是C成长? 排序的自上而下的,对不对?如果它的顶部开始,并生长至底部, 并不像我们给自己多跑道在这里。 我们画种自己陷入了困境, C [11]是正确的,对吧,这是对堆栈帧指针, 这是对返回地址,有没有更多的空间。 那么,有什么含义,那么,如果你搞砸了, 您尝试读取20字节到12个字节的缓冲区? 这8个额外的字节哪里去了? 一切里面,其中有一些是超级重要的。 和最重要的事情,可能是那里的红色方块,将返回地址。 因为假设你是个意外或adversarially 覆盖这4个字节,该指针的地址, 不只是用垃圾,但有一些发生在内存中代表一个实际地址? 什么是implicaiton,逻辑吗? [学生回答,不知所云] >>没错。当foo返回 命中,大括号,程序将继续返回到主, 它会返回的地址是在这红色框。 ,规避软件登记的情况下, 返回到的地址是什么是功能 通常被称为后,你支付的软件,输入你的注册码? 你可以到这里不打算的绝招计算机排序,而是,在这里。 或者,如果你真的很聪明,对手实际上可以输入在键盘上, 例如,而不是实际的单词,而不是20个字符,但假设他或她 某些字符表示代码的类型吗? 它不会是C代码,这将是字符 的表示二进制机器代码,0和1的。 但是,假如他们很聪明足以做到这一点,以某种方式粘贴到的GetString提示 的东西,本质上是编译后的代码, 最后4个字节覆盖了返回地址,地址的输​​入做呢? 它存储在这个红色矩形的缓冲区的第一个字节的地址。 所以,你必须是真聪明,这是一个很大的试验和错误 不好的人,但如果你能弄清楚这个缓冲区有多大, 例如,在输入最后几个字节您提供的程序 发生相当于您的缓冲器的起始地址的, 你可以做到这一点。通常情况下,如果我们说,你好,\ 0,也就是在缓冲区。 但是,如果我们更聪明,我们填补了这一缓冲,我们将统称叫什么攻击代码, A,A,A,A:攻击,攻击,攻击,攻击,这是只是做了一件坏事。 好了,会发生什么,如果你真聪明,你可以这样做: 在这里的红色框是一个数字序列:80,CO,35,08。 请注意,相匹配的数字在这里。 它以相反的顺序,但其他一些时间。 请注意,这个返回地址被故意改变 相同的地址,而不是主要的地址。 因此,如果坏家伙是超级聪明,他或她将要包括在该攻击代码 类似的东西,“删除所有用户的文件”。 或“复制密码”或“创建一个用户帐户,我可以登录到”。 任何东西;这是危险的力量C. 因为你必须通过指针存取记忆体 因此,你可以写任何你想要到一台计算机的内存中。 你可以让一台计算机做任何你想要的简单的 跳在其自己的内存空间。 这样,为了这一天,让许多计划和这么多的网站被攻破 归结到人趁着这个。 这似乎是一个超级复杂的攻击, 但它并不总是这种方式开始。 现实情况是,什么不好的人通常会做的是, 无论它是一个程序,在命令行或GUI程序或网站, 你刚开始提供废话。 您键入一个真正的大词在搜索字段并按下回车键, 你就等着看,如果网站崩溃。 或者,你等着看,如果程序体现了一些错误信息。 因为如果你得到幸运的,因为坏人, 您提供一些疯狂的投入,导致程序崩溃, 这意味着程序员没有预料到你的错误行为 这意味着,有足够的精力,你或许可以 足够的试验和错误,找出如何发动更精确的攻击。 因此,安全的一部分,不只是避免这些攻击完全,但检测 实际上是在寻找日志,看到什么疯狂的输入输入到你的网站的人。 什么样的搜索字词输入到您的网站的人一定的缓冲溢出,希望吗? 而这一切都可以归结为简单的基础知识,什么是一个数组, 和是什么意思分配和使用内存? 相关的,也是这样的。 因此,让我们只是看了一眼里面的硬盘驱动器。 所以,你还记得一两个星期前,当你拖动文件 回收站或垃圾桶,会发生什么呢? [学生]:没有。 >>是的,绝对没有。最后,如​​果你运行低 Windows或Mac OS的磁盘空间,将开始为您删除的文件。 但是,如果你拖动的东西在那里,然后它不是在所有的安全。 你的室友,朋友或家庭成员的所有需要​​做的是双击,瞧。 所有的粗略的,您尝试删除的文件。 所以我们大多数人至少知道,你必须右击或控制点击 清空垃圾桶,或类似的东西。 但即便如此,这并不完全做到的伎俩。 由于发生了什么,当你有你的硬盘驱动器上的文件 一些word文档或者一些JPEG? 这代表您的硬盘驱动器,让我们说这个条子在这里表示该文件, 它是由0和1的一大堆。 会发生什么事时,你不仅该文件拖动到垃圾桶或回收站, 但也空吗? 排序无关。这不是绝对没有。 现在是什么都没有,因为少了一些发生在此表的形式。 因此,有一些种类的数据库或表内的一台计算机的内存 基本上有1列文件名, 1列文件的位置,这可能是位置123,只是一个随机数。 因此,我们可能有一些像x.jpg和位置123。 然后会发生什么,当你清空你的垃圾箱吗? 这消失。但不会消失的“0”和“1”。 那么是什么,然后,连接到PSET 4? 好了,pset的4,只是因为我们不小心删除 紧凑的闪存卡,所有的这些照片, 或者仅仅因为运气不好它成为损坏, 并不意味着,在0和1的是不是仍然存在。 也许他们几个人都失去了,因为有东西损坏 在这个意义上,一些0成为1和1的成为“0”。 不好的事情都可能发生,因为软件bug或有缺陷的硬件。 但许多这些位,也许甚至达到100%,其中仍然存在, 它只是电脑或相机,不知道去哪里JPEG 1日开始 和JPEG 2开始,但如果你作为程序员, 知道,有点悟性,这些JPEG文件或它们看起来像什么, 你可以分析出0和1的,并说,'哦。 JPEG。哦,JPEG。 您可以编写一个程序基本上只是一个while循环 ,恢复这些文件中的每一个。 因此,教训的话,是启动“安全地”删除文件 如果你想完全避免这种情况。是吗? [学生提问,不知所云] >>有更多的内存比你以前 - 哦!这个问题问得好。那么,为什么,然后,清空垃圾桶后, 你的计算机告诉你,你有更多的自由空间比您以前吗? 简单地说,因为它是在撒谎。技术上,你有更多的空间。 因为现在你所说的,你可以把其他的东西,曾经是该文件, 但是,这并不意味着这些位去, 和,这并不意味着位被改变了这一切“0”,例如,为保护您的利益。 与此相反,如果“安全地”擦除文件,或物理破坏的移动设备, 这确实是唯一的办法,有时,解决这一问题。 那么,为什么我们不离开上,半吓人的,我们将看到你在周一。 CS50.TV