ROB BOWDEN: Jag är Rob, och låt oss få sprickbildning. Så kom ihåg från pset spec som vi kommer att behöva använda crypt funktion. För mannen sidan, har vi två hash definiera _xopensource. Oroa dig inte om varför Vi behöver göra det. Och även hash inkluderar unistd.h. Så när det är ur vägen, låt oss komma till själva programmet. Första vi måste göra är att se till användaren angett en giltig krypterad lösenord på kommandoraden. Tänk på att programmet är tänkt köras som dot slash spricka, och sedan krypterade strängen. Så här vi kontrollerar att att argc till två om vi vill fortsätta med programmet. Om argc är inte två, innebär att antingen användaren inte ange en krypterad lösenord på kommandoraden, eller de trädde mer än bara den krypterade lösenord på kommandoraden, där fall vi inte vet vad jag ska göra med den kommandoradsargument. Så om argc var två, kan vi fortsätta. Och här kommer vi att förklara en variabel krypterad. Det är bara att gå till alias den ursprungliga argv1 att så under hela detta program, behöver vi inte kalla det argv1, som då måste man tänka om vad som faktiskt betydde. Så slutligen, vill vi att validera att det krypterade lösenordet för användaren trädde kunde faktiskt varit ett krypterat lösenord. Per mannen sidan av kryptan, den krypterade lösenord måste vara 13 tecken. Här uppe, märker att vi hash definierade kryptera längd som 13. Så vi bara att se till att stränglängd av det krypterade lösenordet är 13. Och om det inte är, vill vi att avsluta programmet. Så när det är ur vägen, kan vi nu faktiskt försöka hitta vad lösenord som gav den krypterade lösenordet var. Här vill vi tag i salt från det krypterade lösenordet. Kom ihåg, per mannen sida, att två första tecknen i en krypterad string, som här - 50ZPJ och så vidare - De två första tecknen ger oss saltet som användes i kryptan funktion. Och här ser vi att saltet var hektar. Så vi vill kopiera de två första tecken, salt längd är hash definieras som två. Vi måste kopiera de två första tecknen i denna samling, salt. Lägg märke till att vi behöver salt längd plus en, eftersom vi fortfarande behöver en null terminator i slutet av vårt salt. Sen ska vi förklara denna array, gäst, storlek max längd plus en, där maxlängd är hash definierad som åtta, eftersom den maximala lösenordet är åtta tecken långt. Och vi kommer att använda detta för att iterera över alla möjliga strängar som kunde vara giltiga lösenord. Så om de giltiga tecken i ett lösenord var bara a, b, och c, så vi skulle iterera över a, b, c, aa, ba, ca, och så vidare, tills vi får se cccccccc - åtta c-talet. Och om vi inte ner ett giltigt lösenord, då måste vi säga att krypterade strängen var inte giltigt till att börja med. Så nu, når vi detta medan 1 slinga. Observera att betyder att det är en oändlig loop. Lägg märke till att det inte finns några break insidan av denna oändlig loop. Det är bara tillbaka uttalanden. Så vi aldrig förvänta att avsluta slingan. Vi förväntar oss bara att avsluta programmet. Jag har lagt detta tryck uttalande till toppen av denna slinga för att bara skriva ut vad vår nuvarande gissning på vad lösenordet är. Nu, vad är denna slinga gör? Det looping över alla möjliga strängar som kan vara giltiga lösenord. Det första vi ska göra är ta vårt nuvarande gissning för vad lösenordet är. Vi tar det salt som vi tog från den krypterade strängen, och vi är kommer att kryptera gissning. Detta kommer att ge oss en krypterad gissning, som vi kommer att jämföra mot den krypterade strängen som användaren skrivas på kommandoraden. Om de är lika, i vilket fall string jämförbara återkommer noll, om de är samma, så gissa var lösenord som genererade krypterade sträng, i vilket fall vi kan skriva ut det som vårt lösenord och retur. Men om de inte var densamma, att innebär vår gissning var felaktig. Och vi vill att iterera till nästa giltiga gissning. Så det är vad denna stund loop försöker göra. Det kommer att iterera vår gissning till nästa giltiga gissning. Lägg märke till att när vi säger att en särskild karaktär i vår gissning har nått max symbol, som här uppe är hash definieras som en tilde, eftersom som är det största ASCII värdet tecken att en användare kan skrivas in vid tangentbord, när karaktären når max symbol, då vi vill skicka det tillbaka till den minsta symbolen, som är ett utrymme, återigen den lägsta ASCII värde symbolen som en användare kan in vid tangentbordet. Så vi kommer att ställa som till ett minimum symbol. Och sedan ska vi gå vidare till nästa tecken. Så hur är våra gissningar kommer att iterera? Tja, om giltiga tecken är a, b, och c, så om vi började med en, det ska iterera till b, ska det iterera till c.. c är vår max symbol, så vi ska ställa c tillbaka till en, den minsta symbolen. Och sedan ska vi iterera index till nästa tecken. Så om den ursprungliga gissning var c, nästa karaktär kommer att vara null terminator. Här nere, märker att om karaktären som vi nu vill ökningen var null terminator, då vi kommer att ställa in den till minimum symbol. Så om gissningen var c, då vår ny gissning kommer att vara AA. Och om vår ursprungliga gissning var cccc, då vår nya gissning kommer att bli aaaaa. Så när vi når den högsta strängen av en viss längd, då är vi kommer att genomföra den lägsta strängen av nästa längd, som kommer att bara vara alla tecken den minsta symbolen. Nu, vad är denna kontroll gör här? Tja, flyttade om index från åttonde tecken till nio tecken - så vi lägger åtta C: s som vår tidigare gissning - då index kommer att fokusera på sista null terminator i vår gissning array, vilket inte är tänkt att faktiskt användas i vår lösenord. Så om vi är fokuserade på att förra null terminator, då vi inte har hittat en lösenord som gäller är med bara åtta tecken, vilket innebär att det inte giltigt lösenord som krypterar till den givna strängen. Och vi måste skriva ut det, säger Vi kunde inte hitta ett giltigt lösenord och retur. Så här while-slinga kommer att iterera över alla möjliga strängar. Om den hittar något som krypterar den förväntade krypterade strängen, det ska returnera det lösenordet. Och det är det inte att hitta något, då den ger, skriver att det kunde inte hitta något. Nu, märker att iterera över alla möjliga strängar är förmodligen kommer att ta en stund. Låt oss se faktiskt hur länge det tar. Låt oss göra crack. Tja, oops - det står odefinierad hänvisning till krypta. Så kom ihåg, för p sätter spec och också mannen sida för krypta som vi måste koppla in kryptan. Nu, standard gör kommandot inte vet att du vill använda denna funktion. Så låt oss kopiera denna klient kommandot och bara lägga på till slutet av det, länkning krypta. Nu, sammanställer det. Så låt oss köra spricka på en given krypterade strängen - så Caesars. Så det var ganska snabbt. Observera att detta slutade på 13. Tja, Caesars krypterat lösenord råkar vara 13. Så låt oss göra ett nytt försök. Låt oss ta Hirschhorn krypterade lösenordet och försök knäcka det. Så märker vi redan har nått tre tecken. Och vi iterera över alla möjliga tre-teckensträngar. Det innebär att vi redan har slut iteration över alla möjliga ena och två teckensträngar. Nu ser det ut som det kommer att ta ett tag innan vi når fyra-teckensträngar. Det kan ta ett par minuter. Det tog inte ett par minuter. Vi finns på de fyra-teckensträngar. Men nu måste vi iterera över alla möjliga fyra-teckensträngar, som som kan ta kanske 10 minuter. Och sedan när vi når fem tecken strängar, måste vi iterera över alla av dem, som kan ta ett par timmar. Och vi måste iterera över alla möjliga sex-teckensträngar, vilket kan ta ett par dagar och så vidare. Så det kan ta en potentiellt mycket lång tid att iterera över alla möjliga åtta tecken och färre strängar. Så märker att detta inte nödvändigtvis en mycket effektiv algoritm för att hitta ett lösenord. Du kanske tror att det finns bättre sätt. Till exempel, lösenordet ZYX! 32AB förmodligen inte är ett mycket vanligt lösenord, medan lösenordet 12345 är troligen mycket vanligare. Så ett sätt att försöka hitta ett lösenord snabbare är att bara titta på lösenord som är vanligare. Så till exempel, kan vi försöka läsa ord från en ordbok och prova alla dessa ord som våra lösenord gissningar. Nu, kanske en lösenord är inte så enkelt. Kanske användaren var något smart och prova att lägga ett nummer till slutet av ett ord. Så kanske deras lösenord var password1. Så du kan prova iteration över alla ord i ordboken med en en läggs till i slutet av det. Och då kanske efter att göra det, kommer du lägga till en två till slutet av den. Eller kanske användaren försöker att bli ännu mer smart, och de vill att deras lösenord för att vara "hacker", men de är kommer att ersätta alla förekomster av e s med tre. Så du kunde göra det också. Iterera över alla ord i ordlistan men byt ut tecken som ser ut som siffror med dessa siffror. Så här sättet, kan du fånga ännu mer lösenord som är ganska vanligt. Men i slutändan, det enda sättet du kan fånga alla lösenord är att brute tvinga iterera över alla möjliga strängar. Så i slutändan behöver du iterera över alla strängar från ett tecken till åtta tecken, vilket kan ta en mycket lång tid, men du måste göra det. Mitt namn är Rob Bowden. Och detta är crack.