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