[Powered by Google Translate] [Week 5] [David J. Malan - Harvard University] [Dit is CS50. - CS50.TV] Dit is CS50, Week 5. Vandaag en deze week, introduceren we een beetje van de wereld van de forensische in de context van het probleem Set 4. Vandaag zal een verkorte lezing zijn omdat er een bijzondere gebeurtenis in hier achteraf. Dus nemen we een kijkje en plagen zowel leerlingen en ouders vandaag de dag met een aantal van de dingen die aan de horizon. Onder hen, vanaf maandag, heb je nog een paar klasgenoten. EDX, Harvard en nieuwe online-MIT initiatief voor OpenCourseWare en nog veel meer, lanceert op de campus van Harvard op maandag, wat betekent dat komende maandag je zult hebben met ingang van de laatste telling, 86.000 extra klasgenoten die zullen worden na samen met CS50's lezingen en secties en walkthroughs en probleem sets. En als onderdeel van dit, zult u lid worden van de inaugurele klasse van CS50 en nu CS50x. Als onderdeel van deze nu realiseren dat er zullen een aantal positieve kanten ook. Om klaar te zijn voor dit, voor de massale aantal studenten, volstaat het om te zeggen dat ook al hebben we 108 TFS en CA's, het is niet helemaal de beste leerling-leraar ratio zodra we raken 80.000 van de studenten. We gaan niet te sorteren zo veel probleem stelt handmatig, dus introduceerde deze week in het probleem set CS50 Controleer zijn, die zal een command-line utility binnen het apparaat dat krijg je als je eenmaal vervolgens bijwerken dit weekend. Je zult in staat zijn om een ​​opdracht, check50, op uw eigen PSET, en je krijgt meteen feedback over de vraag of uw programma juist of onjuist is volgens verschillende ontwerpspecificaties die we hebben. Meer in dat het probleem set specificaties. De CS50x klasgenoten zullen worden met behulp van deze ook. Probleem Set 4 is alles over forensisch onderzoek, en dit PSET was echt geïnspireerd door een aantal real-life stuff waarbij toen ik in graduate school ik geïnterneerd voor een tijdje met Middlesex County District Attorney's kantoor doet forensisch werk met hun voorsprong forensisch onderzoeker. Wat dit voor, bedroeg en ik denk dat ik al een paar weken voorbij, wordt de mis State Police en anderen komen, zouden ze drop off dingen zoals harde schijven en cd's en diskettes en dergelijke, en dan het doel van de forensische kantoor was om na te gaan of er sprake was of was geen bewijs van een soort. Dit was de Special Investigations Unit, dus het was witteboordencriminaliteit. Het was meer verontrustend soort misdaden, alles wat met een soort van digitale media. Het blijkt dat niet dat veel mensen een e-mail te zeggen schrijven, "ik het deed." Dus heel vaak hebben deze forensische zoekacties niet opdagen heel veel fruit, maar soms mensen zouden schrijven dergelijke e-mails. Dus soms werden de inspanningen beloond. Maar om te leiden tot dit forensisch PSET, zullen we introduceren in pset4 een beetje graphics. U waarschijnlijk deze dingen voor lief - JPEG, GIF, en dergelijke - deze dagen. Maar als je echt goed over nadenkt, een beeld, net als het gezicht van Rob, kan worden gemodelleerd als een reeks puntjes of pixels. Bij gezicht Rob, er allerlei kleuren, en begonnen we de afzonderlijke puntjes, ook wel pixels zien, als we eenmaal begonnen om in te zoomen Maar als we vereenvoudigen de wereld een beetje en gewoon zeggen dat dit hier is Rob in zwart-wit, in zwart-wit te vertegenwoordigen, kunnen we gewoon gebruik maken van binaire. En als we gaan binary, 1 of 0, kunnen spreken we dit hetzelfde beeld van lachende gezicht van Rob met dit patroon van bits. 11000011 staat voor wit, wit, zwart, zwart, zwart, zwart, wit, wit. En dus het is niet een enorme sprong dan om te beginnen met praten over kleurrijke foto's, dingen die je zou zien op Facebook of neem met een digitale camera. Maar zeker als het gaat om kleuren, moet je meer bits. En heel gebruikelijk in de wereld van de foto's is het gebruik van niet 1-bits kleur, als dit al doet vermoeden, maar 24-bits kleuren, waar je eigenlijk miljoenen kleuren te krijgen. Zodat in het geval dat we ingezoomd oog Rob, dat was van een aantal miljoenen verschillende kleurrijke mogelijkheden. Dus we zullen introduceren deze in Probleem Set 4 als in de walkthrough, die zal vandaag om 3:30 in plaats van de gebruikelijke 02:30 door lezing van vrijdag hier. Maar video zal online zoals gewoonlijk morgen. We zullen ook kennis maken met een ander bestandsformaat. Dit is met opzet bedoeld om intimiderend op het eerste, maar dit is slechts enkele documentatie voor een C struct. Het blijkt dat Microsoft jaren geleden geholpen populariseren dit formaat riep de bitmap bestandsformaat, bmp, en dit was een super eenvoudige, kleurrijke grafische bestandsformaat die werd gebruikt voor heel wat tijd en soms nog voor behang op desktops. Als je terugdenkt aan Windows XP en de glooiende heuvels en de blauwe hemel, die typisch was een bmp of bitmapafbeelding. Bitmaps zijn leuk voor ons, omdat ze een beetje meer complexiteit. Het is niet zo simpel als dit raster van 0s en 1s. In plaats daarvan, heb je dingen zoals een header aan het begin van een bestand. Dus met andere woorden, de binnenkant van een. Bmp-bestand is een hele hoop van 0s en 1s, maar er is een aantal extra 0s en 1s in. En het blijkt dat wat we waarschijnlijk al vanzelfsprekend al jaren - bestandsformaten zoals. doc of. xls of. mp3,. mp4, ongeacht de bestandsformaten dat u bekend bent met - wat betekent het zelfs betekenen naar een bestandsformaat zijn, want aan het eind van de dag al deze bestanden gebruiken we zojuist 0s en 1s. En misschien die 0s en 1s vertegenwoordigen ABC door middel van ASCII of iets dergelijks, maar aan het eind van de dag, het is nog steeds gewoon 0s en 1s. Dus mensen gewoon af en toe besluiten om een ​​nieuw bestandsformaat uitvinden waar ze standaardiseren welke patronen van bits eigenlijk betekent. En in dit geval hier, de mensen die het ontwerp van de bitmapbestand zei dat bij de eerste byte in een bitmap-bestand als, aangegeven met offset 0 daar, er gaat wat cryptisch benoemde variabele genaamd bfType zijn, die net staat voor bitmap-bestand type, welk type bitmap-bestand is dit. U kunt misschien wel afleiden uit de tweede rij dat offset 2, byte nummer 2, heeft een patroon van 0s en 1s dat wat voorstelt? De grootte van iets. En het gaat van daaruit verder. Dus in Probleem Set 4, zult u worden gelopen door een aantal van deze dingen. We zullen niet eindigen zorgen te maken over hen allen. Maar let op het begint te interessanter rond byte 54: rgbtBlue, Groen en Rood. Als je ooit gehoord van de afkorting RGB - rood, groen, blauw - dit is een verwijzing naar die want het blijkt dat je kunt schilderen alle kleuren van de regenboog met een combinatie van rood en blauw en groen. En in feite zou de ouders in de kamer herinneren enkele van de eerste projectoren. Deze dagen, zie je gewoon een helder licht uit een lens, maar terug in de dag had je de rode lens, de blauwe lens, en de groene lens, en samen vormen ze gericht zijn op een scherm en vormden een kleurrijk beeld. En heel vaak, zou middelbare scholen en middelbare scholen hebben deze lenzen ooit zo iets scheef, dus je was soort van het zien van dubbele of driedubbele beelden. Maar dat was het idee. Je had rood en groen en blauw licht het schilderen van een beeld. En dat hetzelfde principe wordt gebruikt in computers. Dus een van de uitdagingen dan voor u in Probleem Set 4 gaan zijn een paar dingen. Een daarvan is om daadwerkelijk formaat van een beeld, om in een patroon van 0s en 1s, erachter te komen welke brokken van 0s en 1s vertegenwoordigen wat in een structuur als deze, en dan erachter te komen hoe de pixels te repliceren - de rode wijnen, de blues, de greens - binnen zodat wanneer een foto ziet er in eerste instantie als dit, het zou in plaats daarvan er zo uitzien na dat. Onder de andere uitdagingen te gaat worden dat je een forensisch beeld worden overhandigd een effectief bestand van een digitale camera. En op die camera, Once upon a time, waren een hele hoop foto's. Het probleem is dat we per ongeluk gewist of had het beeld een of andere manier beschadigd. Slechte dingen gebeuren met digitale camera's. En dus hebben we snel gekopieerd alle 0s en 1s af van die kaart voor u, redde hen allemaal in een groot bestand, en dan zullen we ze overhandigen aan u in Probleem Set 4 zodat u een programma in C waarmee al die JPEG-bestanden te herstellen ideaal schrijven,. En het blijkt dat JPEG's, ook al zijn ze een beetje zijn van een complex bestandsformaat - ze zijn veel complexer dan dit lachend gezicht hier - het blijkt dat elke JPEG begint met dezelfde patronen van 0s en 1s. Dus met behulp van, uiteindelijk, een while-lus of een for-lus of iets dergelijks, u kunt itereren over alle 0s en 1s in deze forensische beeld, en elke keer zie je de speciale patroon dat is gedefinieerd in het probleem set specificatie, u hier veronderstellen is, met zeer hoge waarschijnlijkheid het begin van een JPEG. En zodra je hetzelfde patroon een bepaald aantal bytes of kilobytes of megabytes later, dan kunt u hier aannemen is een tweede JPEG, de foto die ik nam na de eerste. Laat me stoppen met lezen, dat eerste bestand, start het schrijven van dit nieuwe, en de uitvoer van je programma voor pset4 gaat worden maar liefst 50 JPEG's. En als het niet 50 JPEG's, heb je een beetje een lus. Als u een oneindig aantal JPEG-bestanden, heb je een oneindige lus. Dus dat zal ook een veel voorkomend geval te zijn. Dus dat is wat er aan de horizon. Quiz 0 achter ons, beseffen per mijn e dat altijd zijn er mensen die zijn allebei blij, soort van neutrale, en verdrietig rond quiz 0 tijd. En dan kunt u uit te reiken naar mij, het hoofd TF Zamyla, uw eigen TF, of een van de CA's waarvan je weet als je zou willen om te bespreken hoe het ging. Dus om hier indruk maken op de ouders in de kamer, wat is de CS50 bibliotheek? [Gelach] Good job. Wat is de CS50 bibliotheek? Ja. >> [Student] Het is een vooraf geschreven verzameling code [onverstaanbaar] Oke, goed. Het is een vooraf geschreven verzameling code die we het personeel schreven, bieden wij u, dat voorziet in een aantal gemeenschappelijke functies, Dingen als je me een string, geef me een int - alle functies die hier worden vermeld. Vanaf nu beginnen we echt met deze zijwieltjes eraf. We gaan beginnen weg te nemen een string van u, die recall was gewoon een synoniem voor wat feitelijke gegevens type? >> [Meerdere studenten] Char *. Char *. Voor ouders, dat was waarschijnlijk [maakt suizend geluid]. Dat is goed. Char * beginnen we te zien op het scherm des te meer als we regel te verwijderen uit onze woordenschat, in ieder geval als het gaat om daadwerkelijk schrijven van code. Ook zullen we stoppen met het gebruik van sommige van deze functies zo veel omdat onze programma's gaat krijgen meer verfijnd. In plaats van alleen programma's schrijven die daar te zitten met een prompt knippert, wachten op de gebruiker om iets te typen, krijg je je input van elders. Zo krijg je ze uit een reeks van bits op de lokale vaste schijf. Je zult in plaats daarvan krijgen ze in de toekomst van een netwerkverbinding, sommige website ergens. Dus laten we schil terug deze laag voor de eerste keer en trek de CS50 Appliance en dit bestand genaamd cs50.h, die je hebt # ook voor weken, maar laten we echt zien wat er in deze. De top van het bestand in het blauw is gewoon een hele hoop reacties: informatie over de garantie en licenties. Dit is een soort van een gemeenschappelijk paradigma in software omdat veel software deze dagen is wat open source genoemd, Dit betekent dat iemand de code geschreven en maakte het vrij beschikbaar niet alleen te lopen en te gebruiken, maar om daadwerkelijk te lezen en te veranderen en te integreren in je eigen werk. Dus dat is wat je hebt gebruikt, open source software, zij het in een zeer kleine vorm. Als ik scroll naar beneden langs de opmerkingen, hoewel, beginnen we wat meer bekende dingen te zien. Kennisgeving aan de top hier dat de cs50.h bestand een hele hoop van header-bestanden bevat. De meeste van deze hebben we niet eerder gezien, maar men bekend is. Welke van deze hebben we gezien, zij het kort, tot nu toe? >> [Student] Standaard bibliotheek. Ja, standaard bibliotheek. stdlib.h heeft malloc. Zodra we begonnen te praten over dynamisch geheugen toewijzing, die we zullen terugkomen om volgende week ook, we begonnen met inbegrip van dat bestand. Het blijkt dat bool en waar en onwaar niet werkelijk bestaan ​​in C per se tenzij u onder meer dit bestand hier. We hebben wekenlang zijn inclusief stdbool.h zodat u kunt gebruik maken van de notie van een bool, waar of onwaar. Zonder deze, zou je moeten sorteren van faken en een int gebruiken en gewoon willekeurig aannemen dat 0 false is en 1 is waar. Als we naar beneden scrollen verder, hier is onze definitie van een string. Het blijkt, zoals we al eerder heb gezegd, dat waar deze ster is niet echt belangrijk. U kunt zelfs ruimte rondom. We dit semester zijn het bevorderen van het als dit om duidelijk te maken de ster heeft te maken met het type, maar realiseer net zo gewoon, zo niet een beetje meer gemeenschappelijke, is om daar te zetten, maar functioneel is het hetzelfde. Maar nu, als we lezen verder omlaag, laten we eens een kijkje op GetInt omdat we dat misschien eerst voordat er iets anders dit semester. Hier is GetInt. Dit is wat? >> [Student] Een prototype. >> Dit is slechts een prototype. Vaak hebben we prototypes op de toppen van onze. C-bestanden, maar u kunt er ook prototypes in header-bestanden,. h-bestanden, zoals deze hier zodat wanneer u een aantal functies schrijven die u wilt dat andere mensen om te kunnen gebruiken, hetgeen precies het geval met de CS50 bibliotheek u niet alleen het implementeren van uw functies in iets als cs50.c, ook de prototypes maken niet bovenaan dat bestand maar bovenaan een header bestand. Dan is dat header-bestand is wat vrienden en collega's onder meer met # include in hun eigen code. Dus al die tijd, heb je al met inbegrip van alle van deze prototypes, effectief aan de bovenkant van uw bestand, maar door middel van deze # include mechanisme, die in wezen kopieert en plakt dit bestand in uw eigen. Hier is een aantal tamelijk gedetailleerde documentatie. We hebben vrij veel vanzelfsprekend dat GetInt een int krijgt, maar het blijkt dat er een aantal randgevallen. Wat als de gebruiker een nummer dat is veel te groot, een triljoen, dat kan gewoon niet passen binnen van een int? Wat is het verwachte gedrag? Idealiter is voorspelbaar. Dus in dit geval, als u daadwerkelijk de kleine lettertjes gelezen, je zult echt zien dat als de lijn niet kan worden gelezen, dit rendement INT_MAX. We hebben nog nooit over gehad, maar op basis van de kapitalisatie, wat is het waarschijnlijk? [Student] Een constante. >> Het is een constante. Het is een aantal speciale constante die waarschijnlijk is verklaard in een van die header files dat is hoger in het bestand en INT_MAX is waarschijnlijk iets als ongeveer 2 miljard, het idee is dat omdat we moeten een of andere manier aan te geven dat er iets mis ging, wij, ja, hebben 4 miljard nummers tot onze beschikking: -2 miljard tot 2 miljard, geven of te nemen. Nou, wat gebruikelijk is in de programmering is dat je steelt slechts een van die nummers, maybe 0, misschien 2 miljard, misschien -2 miljard, dus je besteedt een van uw mogelijke waarden, zodat u kunt inzetten voor de wereld dat als er iets mis gaat, zal ik terug deze super grote waarde. Maar u niet wilt dat de gebruiker typt iets cryptisch als 234 ..., echt een groot aantal. U in plaats daarvan generaliseren het als een constante. Dus echt, als je dat anale de afgelopen weken, elke keer dat je de naam GetInt, je had moeten controleren met een als voorwaarde heeft de gebruiker typt INT_MAX, of, meer in het bijzonder, deed GetInt terugkeer INT_MAX, want als het deed, dat betekent eigenlijk dat ze niet typen. Er ging iets mis in dit geval. Dus dit is wat algemeen bekend staat als een schildwacht waarde, wat gewoon betekent bijzonder. Laten we nu eens om te zetten in de. C bestand. De C-bestand bestaat in het toestel voor bepaalde tijd. En in feite, het apparaat heeft het pre-gecompileerd op u in dat ding noemden we objectcode, maar het werkt gewoon niet relevant zijn voor u waar het is omdat het systeem weet in dit geval is: het apparaat. Laten we naar beneden scrollen nu GetInt en hoe GetInt werkt al zien al die tijd. Hier hebben we soortgelijke opmerkingen van tevoren. Laat me in te zoomen op alleen de code gedeelte. En wat we hebben voor GetInt is het volgende. Verder wordt geen input. Het geeft een int, while (true), dus we hebben een bewuste oneindige lus, maar vermoedelijk zullen we uit een of andere manier te breken van deze of retourneren binnen dit. Laten we eens kijken hoe dit werkt. We lijken te zijn met GetString in deze eerste regel in de lus, 166. Dit is nu een goede praktijk, omdat onder welke omstandigheden konden terugkeren GetString een speciaal sleutelwoord NULL? >> [Student] Als er iets mis gaat. Als er iets mis gaat. En wat is er mis kan gaan als je belt iets als GetString? Ja. >> [Student] malloc niet te geven de ints. Ja. Misschien malloc mislukt. Ergens onder de kap, is GetString roept malloc, welk geheugen toewijst, waarmee de computer op te slaan alle tekens dat de gebruiker typt in het toetsenbord. En stel dat de gebruiker had een heleboel vrije tijd en meer getypt, bijvoorbeeld, dan 2 miljard tekens in, meer tekens dan de computer heeft zelfs RAM. GetString moet in staat zijn om dat voor u. Zelfs als dit is een super, super ongewoon hoek geval is, het moet een of andere manier kan dit aan, en zo GetString, als we gingen terug en lees de documentatie, in feite terug NULL. Dus nu als GetString niet door terug te keren NULL, wordt GetInt ploft door terug te keren INT_MAX net als een schildwacht. Dit zijn slechts menselijke conventies. De enige manier waarop je zou weten dat dit het geval is door het lezen van de documentatie. Laten we naar beneden scrollen naar de plaats waar de int daadwerkelijk gekregen. Als ik scroll naar beneden een beetje verder, in de lijn 170, we hebben een commentaar boven deze lijnen. Wij verklaren in 172 een int, n, en een char, c, en vervolgens deze nieuwe functie, die sommige van jullie hebben struikelde over voor, sscanf. Dit staat voor snaar scanf. Met andere woorden, geef me een string en ik zal het scannen op stukjes informatie van belang. Wat betekent dat? Stel dat ik typ in, letterlijk, 123 op het toetsenbord en vervolgens drukt u op Enter. Wat is het gegevenstype van 123 bij geretourneerd door GetString? >> [Student] String. Het is natuurlijk een string, toch? Ik heb een string. Dus 123 is echt, quote-unquote, 123 met de \ 0 op het einde van het. Dat is geen int. Dat is niet een nummer. Het lijkt erop dat een aantal, maar het is niet echt. Dus wat doet GetInt hoeft te doen? Het moet die string van links naar rechts te scannen - 123 \ 0 - en een of andere manier om te zetten in een echte integer. Je zou kunnen uitzoeken hoe dit te doen. Als je terugdenkt aan pset2, u waarschijnlijk kreeg een beetje comfortabel met Caesar of Vigenere dus je kunt itereren over een string, dan kunt u tekens naar ints. Maar ach, het is een hele hoop werk. Waarom niet bellen een functie als sscanf dat voor je doet? Dus sscanf verwacht een argument - in dit geval de naam lijn, dat is een string. Vervolgens geeft u in offertes, zeer vergelijkbaar met printf, wat je verwacht te zien in deze string. En wat ik hier zeg is verwacht ik een decimaal getal en misschien een teken te zien. En we zullen zien waarom dit het geval is in slechts een moment. En het blijkt dat deze notatie nu doet denken aan spullen die we begonnen te praten over iets meer dan een week geleden. Wat is & n en & c doen voor ons hier? >> [Student] Adres van n en het adres van c. Ja. Het geeft me het adres van n en het adres van c. Waarom is dat belangrijk? U weet dat met functies in C, kunt u altijd een waarde of geen waarde terug te keren. U kunt terugkeren een int, een string, een vlotter, een char, wat dan ook, of u kunt ledig terugkeren, maar je kunt alleen maximaal terug te keren een ding. Maar hier willen we sscanf om misschien terug te keren me een int, een decimaal getal, en ook een char, en ik zal de reden waarom de char uit te leggen in een moment. U effectief wilt sscanf twee dingen terug te keren, maar dat is gewoon niet mogelijk in C. U kunt rond die werken door het passeren van twee adressen want zodra je met de hand een functie twee adressen, wat kan die functie doen met hen? >> [Student] Schrijf naar deze adressen. Het kan schrijven die adressen. U kunt gebruik maken van de ster werking en gaan er, voor elk van deze adressen. Het is een soort van deze back-deurmechanisme, maar zeer vaak voor het wijzigen van de waarden van variabelen meer dan een plaats - in dit geval twee. Let nu op Ik controleer voor == 1 en vervolgens terug te keren n als dat in feite de waarde true. Dus wat is er aan de hand? Technisch, alles wat we echt willen dat er gebeurt in GetInt is dit. We willen ontleden, om zo te zeggen, willen we de string te lezen - quote-unquote 123 - en als het lijkt alsof er een aantal daar, wat we sscanf vertellen te doen wordt gesteld dat aantal - 123 - in deze variabele n voor mij. Dus waarom dan had ik eigenlijk dit ook? Wat is de rol van sscanf zeggen dat je misschien ook een teken hier? [Onverstaanbaar student reactie] >> Een decimale punt echt zou kunnen werken. Laten we stellen dat dacht even na. En verder? [Student] Het zou kunnen zijn NULL. >> Goede gedachte. Het zou het nul karakter. Het is eigenlijk niet in dit geval. Ja. >> [Student] ASCII. ASCII. Of laat me generaliseren nog verder. De% c is er alleen voor foutcontrole. We hebben geen er een teken wilt na het nummer, maar wat dit stelt me ​​in staat om te doen is het volgende. Het blijkt dat sscanf naast het opslaan van waarden in n en c in dit voorbeeld, wat het ook doet is het geeft het aantal variabelen zet het waarden binnen Dus als je alleen typt in 123, dan wordt alleen de% d gaat aan te passen, en alleen n wordt opgeslagen met een waarde zoals 123, en niets wordt gezet in c. C blijft een vuilnis waarde, om zo te zeggen - vuilnis omdat het nooit geïnitialiseerd op een bepaalde waarde. Dus in dat geval, sscanf retourneert 1 omdat ik bevolkt 1 van die pointers, in welk geval geweldig, ik heb een int, dus ik gratis de lijn vrij te maken het geheugen dat GetString daadwerkelijk toegewezen, en dan keer ik terug n, anders als je je ooit afgevraagd waar dat Retry verklaring vandaan komt, het komt van hier. Dus als, daarentegen, ik typ in 123foo - slechts enkele willekeurige volgorde van de tekst - sscanf gaat, aantal, getal, f te zien, en het gaat om de 123 in n zet, het gaat om de f in c zet dan en 2 terug te keren. We hebben dus, alleen met behulp van de basisdefinitie van het gedrag sscanf's, een zeer eenvoudige manier - goed complex op het eerste gezicht maar aan het eind van de dag vrij eenvoudige mechanisme - van te zeggen is er een int en zo ja, is dat het enige wat ik heb gevonden? En de witruimte is hier opzettelijk. Als je leest de documentatie voor sscanf, het vertelt je dat als je een stuk witruimte bevatten aan het begin of het einde, sscanf ook kan de gebruiker, om welke reden dan ook, naar spatiebalk 123 geraakt en dat zal legitiem zijn. U zult niet schreeuwen tegen de gebruiker alleen maar omdat ze op de spatiebalk aan het begin of het einde, dat is gewoon een beetje meer gebruikersvriendelijk. Hebt u vragen dan op GetInt? Ja. >> [Student] Wat als je gewoon in een char? Goede vraag. Wat als je zojuist hebt getypt in een char als f en druk op Enter zonder ooit te typen 123? Wat denk je dat het gedrag van deze regel code zou dan kunnen zijn? [Onverstaanbaar student reactie] Ja, dus sscanf kan dat ook te dekken, omdat in dat geval, het is niet van plan om n of c te vullen. Het zal in plaats daarvan 0 terug, in welk geval ik ook het vangen van dat scenario omdat de verwachte waarde ik wil: 1. Ik wil alleen een en slechts een ding in te vullen. Goede vraag. Anderen? Oke. Laten we niet gaan door alle van de functies in hier, maar degene die lijkt te misschien van resterend belang is GetString want het blijkt dat GetDouble GetFloat, GetInt,, GetLongLong alle punter veel van hun functionaliteit GetString. Dus laten we eens een kijkje op hoe hij is hier te vinden. Deze ziet er een beetje ingewikkeld, maar het maakt gebruik van dezelfde fundamenten dat we begonnen te praten over vorige week. In GetString, die neemt geen argument volgens de leegte hier en het geeft een string, ik blijkbaar ben verklaren een string genaamd buffer. Ik weet niet echt wat dat gaat worden gebruikt voor nog niet, maar we zullen zien. Het lijkt erop dat de capaciteit is standaard 0. Niet helemaal zeker waar dit naartoe gaat, niet zeker wat n zal worden gebruikt voor het nog niet, maar nu is het krijgen van een beetje meer interessant. In lijn 243, verklaren we een int, c. Dit is een soort van een domme detail. Een char is 8 bits, en 8 bits kan opslaan hoeveel verschillende waarden? >> [Student] 256. >> 256. Het probleem is als je wilt 256 verschillende ASCII-tekens, waarvan er hebben als je denkt terug - en dat is niet iets om te onthouden. Maar als je terugdenkt aan die grote ASCII grafiek hadden we weken geleden, er in dat geval 128 of 256 ASCII karakters. We gebruikten alle patronen van 0s en 1s-up. Dat is een probleem als je wilt in staat zijn om een ​​fout te detecteren want als je al met 256 waarden voor je personages, je niet echt vooruit te plannen, want nu heb je geen manier om te zeggen, dit is geen legit karakter is dit een foutieve bericht. Dus wat de wereld doet, is dat ze gebruik maken van de volgende grootste waarde, iets als een int, zodat u een gekke aantal bits, 32, voor 4 miljard mogelijke waarden zodat u kunt gewoon uiteindelijk met behulp van in wezen 257 van hen, 1 waarvan een speciale betekenis heeft als een fout. Dus laten we eens kijken hoe dit werkt. In lijn 246, ik heb deze grote while lus die belt fgetc, f betekenis bestand, dus getc, en dan stdin. Het blijkt dat dit nog maar het nauwkeuriger manier om te zeggen lezen input van het toetsenbord. Standaard invoermiddelen toetsenbord, standaard uitvoer betekent scherm, en standaard fout, die we zullen zien in pset4, betekent dat het scherm maar een speciaal deel van het scherm, zodat het niet samengevoegd met de werkelijke productie dat je bedoeld om af te drukken. Maar meer daarover in de toekomst. Dus fgetc betekent gewoon las een teken van het toetsenbord en op te slaan waar? Bewaar het in c. En dan check - dus ik ben gewoon met behulp van enkele Booleaanse voegwoorden hier - controleren of het niet gelijk doet - \ n, dus de gebruiker heeft druk op Enter, willen we op dat punt, het einde van de lus - en wij ook willen controleren voor de speciale constante EOF, die, als u weet of raden, wat doet het voor? >> [Student] End of file. >> End of file. Dit is een beetje onzinnig, want als ik het typen op het toetsenbord, er is echt geen bestand bij deze, maar dit is gewoon soort van de generieke term die wordt gebruikt in de betekenis dat er niets anders is afkomstig van de vingers van de mens. EOF - einde van het bestand. Even terzijde, als je ooit geraakt Control D op je toetsenbord, niet dat je zou nog - je hebt geraakt Control-C - Control D stuurt deze speciale constante genoemd EOF. Dus nu hebben we gewoon wat dynamisch geheugen toewijzing. Als (n + 1> capaciteit). Nu zal ik uitleggen n. N is alleen hoeveel bytes zijn op dit moment in de buffer, de string dat u momenteel opbouwen van de gebruiker. Als u meer tekens in je buffer dan je capaciteit in de buffer te hebben, intuïtief wat we moeten doen is dan toe te wijzen meer capaciteit. Dus ik ga scheren over een aantal van de rekenkundige hier en hier alleen richten op deze functie. Weet je wat malloc is of op zijn minst het algemeen bekend. Raad eens wat realloc doet. >> [Student] Voegt geheugen. Het is niet helemaal het toevoegen van geheugen. Het geheugen bijstuurt als volgt. Als er nog ruimte aan het einde van de string, zodat u meer van dat geheugen dan het oorspronkelijk geeft je, dan krijg je dat er extra geheugen. Je kunt dus gewoon blijven de string personages rug aan rug aan rug aan rug. Maar als dat niet het geval is, omdat je te lang gewacht en iets willekeurig werd plofte in het geheugen zijn maar er is extra geheugen hier beneden, dat is oke. Realloc gaat al het zware werk voor u doen, verplaatst u de tekenreeks die u hebt gelezen in zo ver van hier, het naar beneden neergezet, en dan geeft je wat meer start-en landingsbaan op dat punt. Dus met een golf van de hand, wil ik zeggen dat wat GetString doet wordt het begint met een kleine buffer, misschien een enkel karakter, en als de gebruiker typt in twee personages, GetString eindigt bellen realloc en zegt een teken was niet genoeg, geef me twee tekens. Als je dan lezen via de logica van de lus, het gaat om te zeggen de gebruiker heeft ingevoerd in 3 letters, geef mij nu niet 2 maar 4 letters, geef me dan 8, dan geef me 16 en 32. Het feit dat ik een verdubbeling van de capaciteit telkens betekent dat de buffer niet zal langzaam groeien, gaat het om super snel te groeien. En wat zou het voordeel van dat zijn? Waarom ben ik een verdubbeling van de grootte van de buffer ook al is de gebruiker misschien gewoon behoefte aan een extra teken van het toetsenbord? [Onverstaanbaar student reactie] >> Wat is dat? >> [Student] Je hoeft het niet te laten groeien zo vaak. Precies. Je hoeft het niet te laten groeien zo vaak. En dit is gewoon een soort van je afdekken van uw weddenschappen hier, het idee is dat je niet wilt realloc veel noemen, omdat het de neiging om traag. Elke keer dat je het vraagt ​​het besturingssysteem voor het geheugen, zoals u zult al snel zien in een toekomstig probleem set, het de neiging om enige tijd duren. Dus het minimaliseren van dat bedrag van de tijd, zelfs als je wat ruimte te verspillen, heeft de neiging om een ​​goede zaak. Maar als we lezen het laatste deel van getString hier - en opnieuw begrijpen van elke regel is hier niet zo belangrijk vandaag de dag - merken dat het uiteindelijk dringt er nogmaals malloc en het wijst precies zoveel bytes als het nodig heeft voor de string en dan gooit door te bellen naar het gratis te grote buffer als het inderdaad werd verdubbeld te vaak. Dus in het kort, dat is hoe GetString is al die tijd te werken. Alles wat het doet is lezen een karakter per keer opnieuw en opnieuw en opnieuw, en elke keer dat het heeft wat extra geheugen, vraagt ​​het besturingssysteem voor het door te bellen realloc. Nog vragen? Oke. Een aanval. Nu we begrijpen pointers of op zijn minst zijn steeds beter bekend met pointers, laten we eens kijken hoe de hele wereld begint in te storten als je het niet helemaal te verdedigen tegen vijandige gebruikers, mensen die proberen te hacken in uw systeem, mensen die proberen om uw software te stelen door het omzeilen sommige registratiecode dat ze anders moeten typen inch Neem hier een kijkje naar dit voorbeeld, dat is gewoon C-code die een functie hoofd op de bodem heeft dat noemt een functie foo. En wat is het doorgeven aan foo? [Student] Een enkel argument. >> [Malan] Een enkel argument. Dus argv [1], wat betekent dat het eerste woord dat de gebruiker heeft ingevoerd op de opdrachtregel na a.out of wat dan ook het programma wordt aangeroepen. Dus foo aan de top neemt in een char *. Maar char * is precies wat? >> [Student] Een tekenreeks. [Malan] Een tekenreeks, dus er is hier niets nieuws. Die string is willekeurig wordt genoemd bar. In deze lijn hier, char c [12]; in een soort van semi-technisch Engels, is wat deze lijn aan het doen? [Student] Een array van - >> Array van? >> [Student] Karakters. >> Tekens. Geef me een array van 12 tekens. Dus we zouden kunnen noemen dit een buffer. Het is technisch heet c, maar een buffer in de programmering betekent gewoon een stelletje van de ruimte die je kunt zetten wat spullen binnen Dan tot slot, memcpy we hebben niet eerder gebruikt, maar je kunt waarschijnlijk wel raden wat het doet. Het kopieert het geheugen. Wat doet het? Blijkbaar kopieert bar, de input, in c maar slechts tot de lengte van de bar. Maar er is een bug hier. >> [Student] Je moet de sizeof karakter. >> Oke. Technisch gezien moeten we echt doen strlen (bar) * sizeof (char)). Dat klopt. Maar in het ergste geval hier, laten we aannemen dat Dat is - Oke. Dan is er twee bugs. Dus sizeof (char)); Laten we dit een beetje breder. Dus nu is er nog een bug, dat is wat? >> [Onverstaanbaar student reactie] Controleer voor wat? >> [Student] Controleer op NULL. We moeten in het algemeen worden het controleren op NULL omdat er slechte dingen gebeuren wanneer u de muisaanwijzer NULL is, omdat je zou kunnen eindigen er heen te gaan, en je moet niet altijd te gaan om NULL op dereferentie met de ster operator. Dus dat is goed. En wat kunnen we anders doen? Logisch, er is een fout hier ook. [Student] Controleer of argc is> = tot 2. Dus controleer of argc is> = 2. Oke, dus er is hier drie bugs in dit programma. We zijn nu te controleren of de gebruiker daadwerkelijk getypt in iets in argv [1]. Goed. Dus wat is de derde bug? Ja. >> [Student] C is misschien niet groot genoeg. Goed. We controleerden een scenario. We impliciet gecontroleerd niet meer geheugen dan zou de lengte van bar hoger zijn dan kopiëren. Dus als de string de gebruiker heeft ingevoerd in is 10 tekens lang, Dit zegt alleen kopiëren 10 tekens. En dat is oke. Maar wat als de gebruiker heeft ingevoerd in een woord de prompt als een 20-karakter woord? Dit zegt kopie 20 tekens van bar naar wat? C, ook wel bekend als onze buffer, wat betekent dat je alleen gegevens geschreven tot 8 byte locaties die u niet bezit, en u niet de eigenaar hen in de zin dat je ze nooit toegewezen. Dus dit is wat algemeen bekend staat als de buffer overflow aanval of bufferoverloop aanval. En het is een aanval in de zin dat als de gebruiker of het programma dat er belt uw functie doet dit kwaadwillig, wat er werkelijk gaat gebeuren zou eigenlijk heel slecht. Dus laten we hier een kijkje nemen op deze foto. Deze foto vertegenwoordigt uw stapel van het geheugen. Vergeet niet dat elke keer als je belt een functie die u dit kleine frame op de stack te krijgen en dan nog een en toen nog een en nog een. En tot nu toe, we hebben gewoon een soort van geabstraheerd deze als rechthoeken hetzij op het bord of op het scherm hier. Maar als we inzoomen op een van die rechthoeken, wanneer u een functie foo oproepen, blijkt dat er meer op de stapel binnenkant van dat frame in die rechthoek dan alleen x en y en a en b, zoals we hebben het over swap. Het blijkt dat er een aantal op een lager niveau details, waaronder adresstickers. Zo blijkt bij het belangrijkste noemt foo, de belangrijkste te informeren foo wat de belangrijkste zijn adres in het geheugen van de computer omdat anders, zodra foo gedaan uitgevoerd, zoals in casu, als je eenmaal dit gesloten accolade aan het einde van foo, hoe de heck is foo weet waar de controle van het programma wordt verondersteld om te gaan? Het blijkt dat het antwoord op die vraag is in deze rode rechthoek hier. Dit is een pointer, en het is aan de computer om tijdelijk de zogenaamde stack het adres van algemeen omdat zodra foo gebeurt uitgevoerd, de computer weet waar en wat lijn in de belangrijkste om terug te gaan naar. Opgeslagen Frame aanwijzer heeft betrekking op dezelfde wijze als deze. Char * bar hier staat voor wat? Nu deze blauwe segment is hier foo het frame. Wat is bar? Bar is gewoon het argument om de foo functie. Dus nu zijn we terug bij soort van het vertrouwde beeld. Er is meer spullen en meer afleiding op het scherm, maar dit licht blauwe segment is precies wat we hebben al getekend op het bord voor iets als swap. Dat is het frame voor foo. En het enige wat in het nu is bar, dat is deze parameter. Maar wat moet in de stapel volgens deze code hier? [Student] char c [12]. >> [Malan] char c [12]. Ook dient er 12 vierkanten van het geheugen toegewezen aan een variabele genaamd c, En Wij hebben dat op het scherm. De top is er c [0] en de auteur van dit schema nam niet de moeite het tekenen van alle van de pleinen, maar er zijn zelfs 12 er want als je kijkt naar de onderkant rechts, c [11] als u tellen van 0 is de 12e dergelijke byte. Maar hier is het probleem. In welke richting wordt c groeit? Soort top-down als het begint aan de top en groeit naar de bodem. Het maakt niet uit als we vertrokken ons veel start-en landingsbaan hier helemaal. We hebben soort van geschilderd onszelf in een hoek, en dat c [11] is goed tegen bar, die recht omhoog tegen Opgeslagen Frame wijzer, wat recht is tegen adresstickers. Er is geen plaats meer. Dus wat is de implicatie dan als je verpesten en je probeert te lezen 20 bytes in een 12-byte buffer? Waar zijn die 8 extra bytes ga? >> [Student] Inside - In alles, waarvan sommige super belangrijk. En het allerbelangrijkste, potentieel, is de rode doos daar, adresstickers, want stel dat je per ongeluk of adversarially die 4 bytes te overschrijven, dat pointer adres, niet alleen met afval, maar met een aantal dat gebeurt met een werkelijke adres te vertegenwoordigen in het geheugen. Wat is de implicatie, logisch? >> [Student] Functie gaat om terug te keren naar een andere plaats. Precies. Wanneer foo rendement en hits die accolade, wordt het programma gaat verder niet terug te keren naar de belangrijkste, het gaat om terug te keren naar wat adres is in die rode doos. In het geval van te omzeilen software registratie, wat als het adres dat wordt teruggestuurd naar de functie die normaal wordt aangeroepen nadat je hebt betaald voor de software en ingevoerd uw registratie code? U kunt sorteren van truc de computer in de niet te gaan hier, maar in plaats daarvan te gaan hier. Of als je echt slim, kan een tegenstander daadwerkelijk in te typen op het toetsenbord, bijvoorbeeld, niet een echte woord, niet 20 tekens, maar stel dat hij of zij daadwerkelijk types in een aantal tekens die code vertegenwoordigen. En het niet gaat om C-code te zijn, het is eigenlijk aan de hand te zijn de tekens dat vertegenwoordigen uitvoerbare machinecode, 0s en 1s. Maar stel dat ze slim genoeg om dat te doen, een of andere manier plakken in de GetString prompt iets dat in wezen gecompileerde code, en de laatste 4 bytes te overschrijven die retouradres. En welk adres doet die ingang te doen? Het slaat eigenlijk in deze rode rechthoek het adres van de eerste byte van de buffer. Dus je moet echt slim, en dit is een veel trial and error voor slechte mensen die er zijn, maar als je kunt achterhalen hoe groot deze buffer is zodanig dat de laatste paar bytes in de input die u verstrekt aan het programma toevallig gelijk zijn aan het adres van de start van uw buffer, kunt u dit doen. Als we zeggen normaal gedag en \ 0, dat is wat uiteindelijk in de buffer. Maar als we slimmer en vullen we die buffer met wat we generiek noemen aanval code - AAA, aanval, aanval, aanval - waar dit is gewoon iets dat er iets ergs doet, wat gebeurt er als je echt slim, zou je dit doen. In het rode vak hier is een reeks getallen - 80, C0, 35, 08. Merk op dat het aantal dat is hier past. Het is in omgekeerde volgorde, maar daarover een andere keer. Merk op dat deze terugkeer-adres opzettelijk is gewijzigd naar het adres hier gelijk op, niet het adres van de belangrijkste. Dus als de bad guy is super slim, wordt hij of zij gaat nemen in die aanval code iets als u alle bestanden van de gebruiker of kopieer de wachtwoorden of maak een gebruikersaccount die ik dan kan inloggen op - helemaal niets. En dit is zowel het gevaar en de kracht van C. Omdat u toegang heeft tot het geheugen via de pointers en je kunt alles wat je wilt ook schrijven in het geheugen van een computer, kunt u een computer doen wat je wilt gewoon door te hebben het rond te springen binnen zijn eigen geheugenruimte. En dus tot op de dag zo veel programma's en zo veel websites die in het gedrang neer op mensen gebruik maken van deze. En dit lijkt misschien een super geavanceerde aanval, maar het hoeft niet altijd te beginnen op die manier. De realiteit is dat wat slechte mensen zullen doorgaans doen is, of het nu een programma op een opdrachtregel of een GUI programma of een website, je gewoon beginnen met het verstrekken onzin. U typt in een echt groot woord in het zoekveld en druk op Enter, en je wacht om te zien of de website crasht of je wacht om te zien of het programma manifesteert een foutmelding want als je geluk hebt als de bad guy en u te voorzien wat gekke ingang dat crasht het programma, dat betekent dat de programmeur niet anticiperen op uw slecht gedrag, wat betekent dat u kunt waarschijnlijk met voldoende inspanning, genoeg vallen en opstaan, erachter te komen hoe een nauwkeuriger aanval voeren. Dus net zo goed een onderdeel van de veiligheid is niet alleen het vermijden van deze aanvallen helemaal maar ze op te sporen en eigenlijk op zoek naar logs en zien wat gekke inputs mensen getypt in uw website, welke zoektermen zijn getypt mensen in uw website in de hoop van overvolle of andere buffer. En dit komt allemaal neer op de eenvoudige basisprincipes van wat een reeks en wat betekent het om toe te wijzen en te gebruiken geheugen. Met betrekking tot die toen ook is dit. Laten we gewoon binnen blik van een harde schijf nog maar eens. Herinnert u zich van een week of twee geleden dat wanneer je bestanden slepen naar de prullenbak of prullenmand, wat gebeurt er? >> [Student] Niets. >> Absoluut niets, toch? Uiteindelijk als je weinig schijfruimte, Windows of Mac OS zal het verwijderen van bestanden voor u. Maar als je iets sleept daar, dat is niet helemaal veilig. Al uw huisgenoot of een vriend of familielid hoeft te doen is dubbel klikken en, voila, er is alle schetsmatig bestanden die u probeerde te verwijderen. De meesten van ons in ieder geval weten dat je naar rechts te klikken of klik op en leeg de prullenbak of iets dergelijks. Maar zelfs dan is dat niet helemaal doen de truc want wat er gebeurt als u een bestand op uw harde schijf dat vertegenwoordigt ongeveer Word-document of een JPEG, en dit vertegenwoordigt uw harde schijf, en laten we zeggen dat dit stukje hier is dat bestand, en het is samengesteld uit een hele hoop van 0s en 1s. Wat gebeurt er als je niet alleen dat bestand slepen naar de prullenbak of prullenbak maar ook deze legen? Soort van niets. Het is niet helemaal niets nu. Nu is het gewoon niets, want een beetje iets gebeurt in de vorm van deze tabel. Dus er is een soort van database of tabel binnenkant van een computer het geheugen dat heeft in wezen een kolom voor bestanden de namen en een kolom voor bestanden 'locatie, wanneer die kan plaats 123, maar een willekeurig getal te zijn. Dus we zouden kunnen hebben iets als x.jpeg en locatie 123. Wat gebeurt er dan als je daadwerkelijk leeg je prullenbak? Dat weg gaat. Maar wat gaat niet weg is de 0s en 1s. Dus wat is dan de verbinding met pset4? Nou, met pset4, alleen maar omdat we per ongeluk worden gewist van de compact flash kaart dat had al deze foto's of gewoon omdat het door pech beschadigd raakte betekent niet dat de 0s en 1s niet zijn er nog steeds. Misschien een paar van hen verloren gaan omdat er iets heb beschadigd in de zin dat sommige 0s 1s werd en 1s werd 0s. Slechte dingen kunnen gebeuren als gevolg van buggy software of defecte hardware. Maar veel van die stukjes, misschien zelfs 100% van hen, zijn er nog steeds. Het is gewoon dat de computer of de camera niet weet waar JPEG1 begonnen en waar JPEG2 begonnen. Maar als je, de programmeur, weet met een beetje savvy waar die JPEG-bestanden zijn of hoe ze eruit zien, zodat u kunt analyseren 0s en 1s en zeggen JPEG, JPEG, je kunt schrijven een programma met voornamelijk alleen een voor-of while loop dat herstelt elk van die bestanden in. De les is dan om te beginnen met veilig wissen van uw bestanden Als u wilt helemaal te vermijden dit. Ja. [Student] Hoe komt het dat het zegt over uw computer dat je meer geheugen dan je voorheen deed? Heeft u meer geheugen dan je voorheen deed - >> [student] Meer beschikbare geheugen. Oh. Goede vraag. Dus waarom dan na het legen van de prullenbak heeft uw computer vertellen dat u meer vrije ruimte dan je voorheen deed? In een notendop, omdat hij of zij ligt. Meer technisch, heb je meer ruimte omdat je nu hebt gezegd kun je andere dingen waar het filesysteem ooit was. Maar dat betekent niet dat de bits gaan weg, en dat betekent niet dat de bits worden aangepast om alle 0s bijvoorbeeld voor uw bescherming. Dus daarentegen, als je veilig bestanden wissen of fysiek te vernietigen het apparaat, dat is echt de enige manier soms rond dat. Dus waarom niet laten we op die semi-eng noot, en we zullen u op maandag. [Applaus] [CS50.TV]