[Powered by Google Translate] [Semana 5]
[David J. Malan - Harvard University]
[Esta é CS50. - CS50.TV]
>> Este é CS50 Semana, 5.
Hoxe e esta semana, presentamos un pouco do mundo da ciencia forense
no contexto do conxunto de problemas 4.
Hoxe será unha charla abreviada porque hai un evento especial aquí despois.
Entón, imos dar un ollo e provocar estudantes e pais de hoxe
con algunhas das cousas que son no horizonte.
>> Entre eles, a partir do luns, terá un pouco máis compañeiros.
EDX, Harvard e MIT nova iniciativa en liña para OpenCourseWare e máis,
está lanzando no campus de Harvard, o luns, o que significa que o luns
terá, a partir de última conta, 86 mil compañeiros adicional
que vai seguir xunto con conferencias CS50 e seccións
e orientacións e conxuntos de problemas.
E, como parte diso, vai converterse membros da clase inaugural do CS50 e agora CS50x.
Como parte deste momento, entender que haberá algunhas upsides tamén.
Para se preparar para iso, para o gran número de estudantes,
basta dicir que, aínda que teñamos 108 TFS e CAS,
non é así a mellor relación profesor-alumno, unha vez que alcanzou 80.000 dos alumnos.
Non imos ser problema para moitos clasificación define manualmente
así introducido esta semana no conxunto de problemas será CS50 Check,
que vai ser unha utilidade de liña de comandos dentro do aparello
que vai ter unha vez que actualiza-lo máis tarde este fin de semana.
Vai ser capaz de executar un comando, check50, no seu propio pset,
e vai ter un feedback instantáneo para saber se o seu programa é correcta ou incorrecta
acordo coas especificacións de deseño diferentes que nós fornecen.
Máis sobre iso na especificación do conxunto de problemas.
Os compañeiros CS50x vai usar isto tamén.
>> Set problema 4 é todo sobre a ciencia forense,
e este pset estaba realmente inspirado por algunhas cousas na vida real
polo que, cando estaba na facultade eu internados por un tempo
na Fiscalía do Condado de Middlesex District está facendo o traballo forense
co seu principal investigador forense.
O que isto representa, como eu creo que eu mencionen algunhas semanas pasado,
é a policía do Estado de masa ou outros entraba,
eles ían deixar as cousas como discos duros, CDs e disquetes e similares,
e, a continuación, o obxectivo da oficina forense foi comprobar
se houbo ou non era evidencia de calquera tipo.
Esta foi a Unidade de Investigacións Especiais, por iso era delito de colo branco.
Era unha especie máis preocupante de crimes, calquera cousa que involucre algún tipo de comunicación dixital.
Acontece que non que moitas persoas escriben un e-mail dicindo: "Eu fixen iso."
Entón, moitas veces, estas investigacións forenses non apareceu todos os froitos que moito,
pero ás veces as persoas escriben correo-e dese tipo.
Entón, ás veces, os esforzos foron recompensados.
>> Pero, para levar ata este pset forense, estaremos introducindo no pset4 un pouco de gráficos.
Probablemente levar estas cousas para concedida - JPEGs, GIFs e outros - estes días.
Pero se realmente pensa sobre iso, unha imaxe, así como o rostro de Rob,
pode ser modelada como unha secuencia de puntos ou píxeles.
No caso da cara de Rob, hai todo tipo de cores,
e comezamos a ver os puntos individuais, tamén coñecidos como píxeles,
unha vez que comezou a facer zoom in
Pero simplificar o mundo un pouco e dicir que iso aquí é Rob en branco e negro,
para representar o branco e negro, podemos usar só binario.
E se imos usar binario, 1 ou 0, podemos expresar esta mesma imaxe
de rostro sorrinte de Rob con ese patrón de bits.
11000011 representa o branco, branco, negro, branco, negro, negro, branco, branco.
E por iso non é un gran salto a continuación, comezar a falar fotografías de cores,
cousas que vería no Facebook ou levar unha cámara dixital.
Pero, certamente, cando se trata de cores, ten que máis bits.
É bastante común no mundo das fotografías é usar unha cor non-bit,
como iso suxire, pero cor de 24 bits, onde realmente obter millóns de cores.
Así como no caso cando o zoom no ollo do Rob,
que era un número calquera de millóns de distintas posibilidades de cores.
Entón, nós imos introducir esta no Conxunto Problema 4, así como no paso a paso,
que será hoxe ás 3:30 en vez de 2:30 habitual por mor da charla do venres aquí.
Pero o vídeo estará en liña mañá como de costume.
>> Tamén imos presenta-lo a outro formato de arquivo.
Este é deliberadamente quería ollar intimidador en principio,
pero iso é só unha documentación algunha para unha struct C.
Acontece que hai anos a Microsoft axudou a popularizar este formato
chamado formato de ficheiro bitmap, bmp, e este foi un super sinxelo, formato de arquivo gráfico colorido
que foi usado por algún tempo e, ás veces aínda para fondos de pantalla en escritorios.
Se pensas que volta para o Windows XP e os outeiros eo ceo azul,
que era tipicamente unha imaxe BMP ou bitmap.
Bitmaps son divertido para nós, porque eles teñen un pouco máis de complexidade.
Non é tan sinxelo coma esta reixa de 0s e 1s.
En vez diso, ten cousas como unha cabeceira no inicio dun arquivo.
Polo tanto, noutras palabras, dentro dun arquivo bmp. É un monte de 0s e 1s,
pero hai algún adicional 0s e 1s alí.
E resulta que o que probablemente xa un dato adquirido hai anos -
formatos de arquivo como. doc ou. xls ou. mp3, mp4., independentemente dos formatos de ficheiro
que está familiarizado con - o que iso significa mesmo ser un formato de arquivo,
porque ao final do día, todos estes ficheiros usan teñen só 0 e 1.
E quizais os 0s e 1s representan ABC través ASCII ou similar,
pero ao final do día, aínda é só 0s e 1s.
Así, os seres humanos só ocasionalmente deciden inventar un novo formato de arquivo
onde padronizar o que patróns de bits vai realmente significar.
E, neste caso aquí, o persoal que proxectou o formato de arquivo bitmap
dixo que o primeiro byte nun arquivo bitmap, como denotado por 0 compensado alí,
alí vai ser un enigmaticamente chamado bfType variable chamada,
que só queda para o tipo de ficheiro de bitmap, o tipo de ficheiro bitmap é esta.
Pode deducir quizais da segunda liña que compensar 2, número de bytes 2,
ten un nivel de 0s e 1s que representa o que? O tamaño de algo.
E vai de alí.
Entón, o Conxunto Problema 4, vai ser orientado por algunhas destas cousas.
Non vai acabar se preocupar con todos eles.
Pero teña en conta que comeza a estar interesante en torno a byte 54: rgbtBlue, verde e vermello.
Se vostede xa escoitou a sigla RGB - vermello, verde, azul - esta é unha referencia a ese
pois verifícase que pode pintar todas as cores do arco da vella
cunha combinación de vermello e azul e verde.
E, de feito, os pais no cuarto pode recordar algúns dos primeiros proxectores.
Estes días, só ve unha luz brillante que sae dunha lente,
pero volta o día en que tivo a lente vermella, lento azul, ea lente verde,
e, xuntos, destinado a unha pantalla e formou unha imaxe en cor.
E, moitas veces, escolas de ensino medio e escolas secundarias tería aquelas lentes
levemente torto, para que eran unha especie de ver imaxes dobres ou triplas.
Pero esa era a idea. Tiña luz vermella, verde e azul pintar un cadro.
E ese mesmo principio é usado en computadoras.
>> Así, entre os retos, a continuación, para que en Problema Set 4 van ser algunhas cousas.
Un deles é para redimensionar unha imaxe, para tomar un patrón de 0s e 1s,
descubrir cal anacos de 0s e 1s representan o que unha estrutura como esta,
e entón descubrir como replicar os píxeles - os vermellos, os azuis, os verdes -
dentro de xeito que, cando unha imaxe queda así, inicialmente,
pode parecer que esta vez despois diso.
Entre os outros desafíos que tamén vai ser que vai ser entregado unha imaxe forense
dun arquivo real dunha cámara dixital.
E nesa cámara, era unha vez, foron unha morea de fotos.
O problema é que accidentalmente borrados ou tivo a imaxe corrupta dalgún modo.
Cousas malas suceden con cámaras dixitais.
E, así, axiña copiado todo o off 0s e 1s que a tarxeta para ti,
garda-los todos nun arquivo grande, e despois imos entrega-los a vostede no conxunto de problemas 4
de xeito que podes escribir un programa en C co cal se recuperar todas esas JPEGs, idealmente.
E ocorre que JPEGs, aínda que sexan un pouco de un formato de ficheiro complexo -
son moito máis complexos do que este sorriso aquí -
verifícase que todos os JPEG iníciase cos mesmos estándares de 0s e 1s.
Entón, usando, en última análise, un loop while ou un loop for ou similar,
pode iterar sobre os 0s e 1s nesta imaxe forense,
e cada vez que ver o patrón especial que está definido na especificación conxunto de problemas,
pode asumir aquí é, con gran probabilidade, o inicio dun JPEG.
E así que atopar o mesmo patrón algún número de bytes
ou kilobytes ou megabytes máis tarde, pode asumir aquí é un JPEG segundo,
a foto que eu tomei despois da primeira.
Deixe-me deixar de ler este ficheiro en primeiro lugar, comezar a escribir este novo,
ea saída do seu programa para pset4 vai ser preto de 50 JPEGs.
E se non é 50 JPEGs, ten un pouco de un loop.
Se vostede ten un número infinito de JPEGs, ten un loop infinito.
De xeito que tamén será moi caso común.
Entón, iso é o que está no horizonte.
>> 0 Quiz detrás de nós, entender por meu correo-e que, invariablemente, hai persoas que son ambos felices,
especie de neutro, e triste ao redor cuestionario tempo 0.
E por favor, chegar a min, a cabeza TF Zamyla, a súa propia TF,
ou un dos CAs que vostede sabe, se desexa discutir como as cousas correron.
>> Entón, para impresionar os pais aquí na sala, o que é a biblioteca CS50?
[Risas] Bo traballo.
¿Que é a biblioteca CS50? Si >> [Alumno] É un conxunto pre-escritura de código [inaudível]
Ok, bo.
É un conxunto de pre-escritura de código que o persoal escribiu, ofrecemos a vostede,
que ofrece algunhas funcións comúns,
cousas como me unha corda, me un int - todas as funcións que están listados aquí.
>> A partir de agora, comezamos a realmente tomar esas Rodas pequenas.
Nós imos comezar a tomar unha serie de ti,
que recordo era só un sinónimo para o tipo de datos real? >> [Varios alumnos] char *.
* Char. Para os pais, que foi, probablemente, [son fai whooshing]. Isto é bo.
* Char imos comezar a ver na pantalla todo o máis que podemos eliminar secuencia do noso vocabulario,
polo menos cando se trata de que realmente escribir código.
Do mesmo xeito, nós imos deixar de usar algunhas desas funcións tanto
porque os nosos programas están indo para obter máis sofisticado.
En vez de só escribir programas que están alí cun chiscar ventá,
á espera de que o usuario escriba algo, terá entrada dende outro sitio.
Por exemplo, vai leva-los a partir dunha serie de bits no disco duro local.
Vai en vez leva-los no futuro a partir dunha conexión de rede,
algún sitio en algún lugar.
>> Entón, imos pelar esa capa por primeira vez e tirar para arriba o Appliance CS50
e este ficheiro chamado cs50.h, o que ten # incluíndo por semanas,
pero imos ver realmente o que está dentro do presente.
O inicio do ficheiro en azul é só unha morea de comentarios:
información sobre a garantía e licenzas.
Esta é unha especie de paradigma común en software
porque unha morea de software nos días de hoxe é o que se chama de código aberto,
o que significa que alguén teña escrito o código e tornouse dispoñible gratuitamente
non só para executar e para usar, pero para realmente ler e modificar e integrar no seu propio traballo.
Entón é iso que está a usar, o software de código aberto, aínda que dunha forma moi pequena.
Se rolar para abaixo tras os comentarios, pero imos comezar a ver algunhas cousas máis familiares.
Aviso arriba aquí que o arquivo cs50.h inclúe un conxunto de ficheiros de cabeceira.
A maioría destes, non vimos antes, pero un é familiar.
Cal destes vimos, aínda que brevemente, ata agora? >> [Alumno] biblioteca estándar.
Si, biblioteca estándar. stdlib.h ten malloc.
Unha vez que comezamos a falar sobre distribución dinámica de memoria,
que imos volver para a próxima semana, así, comezamos incluíndo o arquivo.
Acontece que bool e certo e falso en realidade, non existe en C, por si só
a menos que inclúa este ficheiro aquí.
Temos de semana foi incluído stdbool.h
de modo que pode empregar a noción de un. bool, verdadeiro ou falso
Sen iso, tería que clasificar de finxir e utilizar un int
e só arbitrariamente asumir que 0 é falso e 1 é verdadeira.
Se rolar máis, aquí é a nosa definición dunha cadea.
Acontece que, como xa dixen antes, que esta estrela é onde realmente non importa.
Pode até ter todo o espazo ao redor.
Nós neste semestre foron promovendo-o como esta para deixar claro
que a estrela ten que ver co tipo,
pero enténdese tan común, se non un pouco máis común,
é poñer-lo alí, pero funcionalmente é a mesma cousa.
Pero agora, se lermos máis abaixo, imos dar un ollo a GetInt
porque usamos que, se cadra, antes de máis nada neste semestre.
Aquí está GetInt. Isto é o que? >> [Alumno] Un prototipo. >> Este é só un prototipo.
Moitas veces, hai que poñer prototipos arriba da nosa. Arquivos c,
pero tamén pode poñer prototipos en arquivos de cabeceira, arquivos. h, como esta aquí
de xeito que cando escribe algunhas funcións que quere que outras persoas para ser capaz de utilizar,
que é o caso da biblioteca CS50,
non só aplicar as súas funcións en algo así como cs50.c,
tamén poñer os prototipos non na parte superior do ficheiro, pero na parte superior de un arquivo de cabeceira.
A continuación, o ficheiro de cabeceira é o que os amigos e compañeiros de incluír
con # incluír no seu propio código.
Entón todo este tempo, está incluíndo todos os prototipos,
efectivamente no cume do seu arquivo, pero por medio deste mecanismo # include,
que esencialmente copia e pega este ficheiro no seu propio país.
Aquí está algunha documentación bastante detallada.
Nós practicamente un dato adquirido que GetInt recibe un int,
pero acontece que hai algúns casos de canto.
E se o usuario escribe un número que é moi grande, un quintilhões,
que simplemente non pode caber dentro dun int? Cal é o comportamento esperado?
Ideal, é previsible.
Polo tanto, neste caso, se realmente ler a copia fina,
realmente ver que, se a liña non se pode ler, INT_MAX este retorno.
Nós nunca falamos sobre iso, pero con base na súa capitalización, o que pode ser?
[Alumno] A constante. >> É unha constante.
É unha constante especial que é, probablemente, declarou un deses ficheiros de cabeceira
que é ata maior no arquivo, e INT_MAX é probablemente algo como preto de 2 millóns,
A idea é que, porque necesitamos de algunha maneira significar que algo deu mal,
Temos, si, ten 4 millóns de números á nosa disposición: -2000000000 en ata 2 millóns, máis ou menos.
Ben, o que é común en programación é vostede roubar só un deses números,
quizais 0, quizais 2 millóns, quizais -2000000000,
así gasta un dos seus valores posíbeis de xeito que pode cometer ao mundo
que, se algo sae mal, eu vou volver ese valor super grande.
Pero non quere que o usuario escriba algo enigmático como 234 ..., un número moi grande.
Vostede xeneraliza-lo en vez como unha constante.
Entón, realmente, se estaba sendo anal nas últimas semanas, a calquera hora que chamou GetInt,
debería ter benvida a comprobar unha condición, se fixo o tipo de usuario INT_MAX,
ou, máis especificamente, fixo GetInt INT_MAX retorno, porque se o fixese,
que realmente significa que non escriba-lo. Algo deu mal neste caso.
Polo tanto, este é o que é xeralmente coñecido como un valor de sentinela, o que significa só especial.
>> Imos agora volver ao arquivo c ..
O ficheiro C existiu no aparello por algún tempo.
E, de feito, o aparello ten precompilados para ti nesa cousa que chamamos de código obxecto,
pero simplemente non importa a onde está porque o sistema sabe
neste caso en que é: aparello.
Imos rolar agora getInt e ver como GetInt vén traballando todo este tempo.
Aquí temos comentarios similares antes.
Deixe-me ampliar só o código porción.
E o que temos para GetInt é o seguinte.
Non é preciso de entrada.
El retorna un int, mentres (certo), por iso temos un loop infinito deliberada,
pero probablemente imos saír desa forma ou volver a partir desta.
>> Imos ver como funciona isto.
Parece que estamos usando GetString nesta primeira liña dentro do loop, 166.
Isto agora é unha boa práctica, porque en que circunstancias podería volver GetString
a palabra chave NULL especial? >> [Alumno] Se algo sae mal.
Se algo sae mal. E o que podería dar mal cando chamar algo así como GetString?
Si >> [Alumno] Malloc falla en darlle os ints.
Si Quizais malloc falla.
En algún lugar debaixo do capó, GetString está chamando malloc, que aloca memoria,
que permite que a tenda de informática de todos os personaxes
que o usuario escribe no teclado.
E supoña que o usuario tiña unha morea de tempo libre e ingresaran, por exemplo,
de 2 millóns de carácteres, máis personaxes que o ordenador aínda ten RAM.
GetString ten que ser capaz de significar que para ti.
Aínda que este é un super, super-canto se inusual,
ten dalgún modo ser capaz de tratar con isto,
e así GetString, volveuse e ler a súa documentación, fai NULL retorno feito.
Polo tanto, agora GetString falla, retornando NULL, GetInt vai fallar, retornando INT_MAX
só como unha sentinela. Estes son só convencións humanas.
O único xeito que sabe que este é o caso a través da lectura da documentación.
>> Imos cambiar ata onde o int é realmente chegou.
Se rolar un pouco máis, na liña 170, temos un comentario enriba destas liñas.
Declaramos en 172 un int, n, e un char, c, e, a continuación, esta nova función,
que algúns de vostedes que tropeçado antes, sscanf.
Isto significa scanf cadea.
Noutras palabras, dáme unha corda e eu debería buscar pezas de información de interese.
O que significa isto?
Supoña que eu escribir, literalmente, 123 no teclado e prema a tecla Intro.
Cal é o tipo de datos de 123 cando retornou por GetString? >> [Alumno] Cadea.
É evidente que é unha cadea, non? Eu teño un string.
Entón, é realmente 123, comiñas pecha comiñas, 123 co 0 \ ao final do mesmo.
Isto non é un int. Isto non é un número. Parece un número, pero iso non é verdade.
Entón, o que GetInt teño que facer?
Ten que analizar esa secuencia esquerda a dereita - 123 \ 0 - e dalgunha forma converter a un enteiro real.
Vostede podería descubrir como facelo.
Se pensas que volta para pset2, probablemente ten un pouco cómodo con César
ou Vigenère, así pode iterar sobre unha corda, pode converterse caracteres para ints.
Pero que demo, é un monte de traballo.
Por que non chamar a unha función como sscanf que fai isto para vostede?
Entón sscanf espera un argumento - neste caso chamado de liña, que é unha cadea.
Vostede, entón, indicar entre comiñas, moi semellante ao printf, o que espera a ver nesta secuencia.
E o que eu estou dicindo aquí é que eu espero ver un número decimal e quizais un personaxe.
E imos ver por que este é o caso en só un momento.
E ocorre que esta notación é agora lembra de cousas que comezaron a falar sobre
pouco máis dunha semana.
¿Que é & n & C e facendo por nós aquí? >> [Alumno] Enderezo n e enderezo do c.
Si Está me dando o enderezo de n e enderezo do c. Por que iso é importante?
Vostede sabe que con funcións en C, sempre pode voltar un valor ou ningún valor.
Podes devolver un int, unha corda, unha boia, un char, calquera que sexa, ou pode voltar baleiro
pero só se pode retornar unha cousa ao máximo.
Pero aquí queremos sscanf para volver me quizais un int, un número decimal,
e tamén un. char, e eu vou explicar por que o char nun momento
Vostede efectivamente quere sscanf para voltar dúas cousas, pero iso non é posible en C.
Pode resolver iso pasando en dous enderezos
porque así que entrega unha función de dous enderezos,
o que pode facer esa función con eles? >> [Alumno] Escriba para estes enderezos.
Pode escribir para eses enderezos.
Podes utilizar a operación de estrela e ir para alí, para cada un destes enderezos.
É unha especie de este mecanismo de back-door, pero moi común para cambiar os valores das variables
máis que un único local - neste caso, dous.
Agora repare que eu estou comprobando == 1 e despois retornando n se isto, de feito, avaliar a realidade.
Entón, o que está a suceder? Tecnicamente, todo o que realmente quere que aconteza en GetInt é esta.
Queremos analizar, por así dicir, queremos ler a secuencia - entre comiñas-123 -
e parece que hai un número alí, o que estamos dicindo sscanf facer
é poñer ese número - 123 - Esta variable n para min.
Entón, por que entón eu realmente teño iso tamén?
Cal é o papel de sscanf dicindo que tamén se pode obter un personaxe aquí?
[Resposta do alumno inaudível] >> Un punto decimal realmente podería funcionar.
Imos soster que penso por un momento. O que máis?
[Alumno] Podería ser NULL. >> Bo pensamento. Podería ser o carácter nulo.
Non é certo neste caso. Si >> [Alumno] ASCII.
ASCII. Ou deixe-me xeneralizar aínda máis.
O c% non é só para comprobación de erros.
Nós non queremos que haxa un personaxe despois do número,
pero o que iso me permite facer é o seguinte.
Acontece que sscanf, ademais de almacenar valores de n e c neste exemplo aquí,
o que tampouco é el retorna o número de variables que poñer valores dentro
Entón, se escribir só en 123, entón só o% d vai corresponder,
e só n queda almacenado cun valor como 123,
e nada é posto en c.
C segue a ser un valor de lixo, por así dicir -
lixo, porque iso nunca foi inicializada con algún valor.
Entón, nese caso, sscanf retorna 1 porque eu cuberto un dos punteiros,
caso en que gran, eu teño un int para que eu liberar a liña para liberar a memoria
GetString que efectivamente asignado, e entón eu volver n,
máis se xa se preguntas onde que repetir declaración vén, vén aquí.
Así, se, pola contra, eu escriba 123foo - só unha secuencia aleatoria de calquera texto -
sscanf vai ver número, número, número, f,
e vai poñer o 123 en n; vai poñer o f en C e despois volver 2.
Entón temos, só usando a definición básica de comportamento sscanf, dun xeito moi simple -
así, complexo, a primeira vista, pero ao final do día mecanismo relativamente simple -
de dicir que hai un int e se é así, é que a única cousa que eu atope?
E o espazo en branco aquí é deliberada.
Se ler a documentación para sscanf, dille que, se incluír unha peza de espazo en branco
, No inicio ou no final, sscanf tamén ha permitir que o usuario, por calquera razón,
a bater 123 barra de espazo e que será lexítimo.
Non vai berrar co usuario só porque bateu a barra de espazo
no inicio ou no final, que é só un pouco máis user-friendly.
>> Algunha preguntas, entón no GetInt? Si >> [Alumno] E se só poñer un char?
Boa pregunta.
E se acaba de escribir un char como f e prema Intro sen nunca escribindo 123?
¿Que pensas que o comportamento desta liña de código sería entón?
[Resposta do alumno inaudível]
Si, entón sscanf pode cubrir iso tamén porque, nese caso, non vai encher n ou c.
Vai en vez volver 0, caso en que eu tamén estou pegando este escenario
porque o valor esperado que quero é 1.
Eu só quero unha e só unha cousa a ser cuberto. Boa pregunta.
>> Outros? Todo ben.
>> Non imos pasar por todas as funcións aquí,
pero o que parece ser, quizais, de participación remanescente é GetString
pois verifícase que GetFloat, GetInt, GetDouble, GetLongLong
todos punto moito de súa funcionalidade para GetString.
Entón, imos dar un ollo a como é aplicado aquí.
Este parece un pouco complexo, pero usa os mesmos fundamentos
que comezamos a falar sobre a semana pasada.
En GetString, que leva ningún argumento segundo o baleiro aquí
e retorna un string, eu parecer estou declarando unha cadea chamada buffer.
Eu realmente non sei o que vai ser usado para aínda, pero imos ver.
Parece que a capacidade é, por defecto 0.
Non é ben certo onde iso vai dar, non sei o que n vai ser usado para, con todo,
pero agora está quedando un pouco máis interesante.
Na liña 243, declaramos un int, c.
Esta é unha especie de un detalle estúpido.
Un char é de 8 bits, e 8 bits pode almacenar cantos valores diferentes? >> [Alumno] 256. >> 256.
O problema é se quere ter 256 diferentes carácteres ASCII, que hai
se pensas que volta - e iso non é algo para memorizar.
Pero se pensas que volta a ese gráfico gran ASCII tivemos semanas,
foron, neste caso 128 ou 256 carácteres ASCII.
Usamos os patróns de ata 0s e 1s.
Isto é un problema se quere ser capaz de detectar un erro
porque se xa está a usar 256 valores para os seus personaxes,
realmente non planificar con antelación, porque agora non ten ningunha forma de dicir,
este non é un personaxe legal, é dicir algunha mensaxe incorrecta.
Entón, o que o mundo ten que usan o maior valor próximo, algo así como un int,
para que teña un número tolo de bits, 32, para 4 mil millóns de valores posíbeis
de xeito que pode simplemente acabar empregando, esencialmente, 257 deles,
Un dos cales ten algún significado especial como un erro.
>> Entón imos ver como funciona isto.
Na liña 246, eu teño esa gran loop while que está chamando fgetc,
f ficheiro significado, de xeito getc, e despois stdin.
Acontece que esta é só a forma máis precisa de dicir ler a entrada do teclado.
Teclado medio estándar de entrada, saída estándar significa pantalla,
e erro estándar, o que veremos na pset4, significa que a pantalla
pero unha parte especial da pantalla de xeito que non é confundida con saída real
que desexa imprimir. Pero máis sobre iso no futuro.
Entón fgetc significa só ler un caracter do teclado e almacena-lo onde?
Garda o en c.
E a continuación, comprobar - por iso estou usando só algunhas conxuncións booleanos aquí -
asegúrese de que non é igual - \ n, de xeito que o usuario prema Intro, queremos deixar nese punto,
fin do ciclo - e nós tamén queremos comprobar a EOF constante especial,
que se indica ou adiviñar, o que significa isto? >> [Alumno] Fin do arquivo. Fin >> de arquivo.
Este é o tipo de absurdo, porque se eu estou escribindo no teclado,
non hai realmente ningún arquivo implicado niso,
pero iso é só unha especie de termo xenérico usado para significar
que nada máis é que vén dedos dos humanos.
EOF - final do arquivo.
Como un aparte, se xa alcanzou Control D no seu teclado non, que tería aínda -
bateu Control C - Control D envía esta constante especial chamado EOF.
Polo tanto, agora só temos algúns asignación dinámica de memoria.
>> Así, (n + 1 Capacidade>). Agora eu vou explicar n.
N é só cantos bytes están actualmente no búfer,
a secuencia que está a construírse a partir do usuario.
Se ten máis caracteres no seu buffer que ten capacidade de buffer,
intuitivamente o que temos que facer, entón, é reservar máis capacidade.
Entón eu vou para saltar un pouco da aritmética aquí e centrar só esta función aquí.
Sabe o que malloc é ou son, polo menos xeralmente familiar.
Adiviña o que realloc fai. >> [Alumno] Engade memoria.
Non é así a adición de memoria. É realoca memoria como segue.
Se aínda hai espazo no final da cadea para darlle máis que a memoria
do que orixinalmente lle dá, entón vai ter que memoria adicional.
Entón podes só seguir poñendo personaxes da corda de costas cara atrás, cara atrás.
Pero se ese non é o caso, porque esperou moito tempo
e foi algo aleatorio xogou na memoria non
pero non hai memoria extra aquí, todo ben.
Realloc vai facer todo o traballo pesado para ti,
mover a secuencia que xa leu en así moi lonxe de aquí, colocar-lo alí en baixo,
e despois darlle un pouco máis de pista naquel momento.
>> Así, cun aceno de man, deixe-me dicir que o que está facendo GetString
é que está comezando con un buffer pequeno, quizais un carácter único,
e se o usuario escribe en dous personaxes, GetString acaba chamando realloc e di
un personaxe non foi o suficiente, dáme dous personaxes.
Entón, se ler a lóxica do circuíto, que vai dicir
o usuario introduciu 3 caracteres dáme agora non dous, senón catro personaxes,
entón me dea 8, a continuación, dar-me 16 e 32.
O feito de que eu estou dobrando a capacidade de cada vez
significa que o buffer non vai crecer lentamente, vai medrar super rápido.
E o que podería ser a vantaxe disto?
Por que eu estou dobrando o tamaño do buffer
aínda que o usuario só precisa dun personaxe extra a partir do teclado?
[Resposta do alumno inaudível] >> ¿Que é iso? >> [Alumno] Non ten que crecer sempre.
Exactamente. Non ten que crecer sempre.
E este é só un tipo de cobertura está aquí as súas apostas,
A idea é que non quere chamar realloc moito, porque tende a ser lenta.
Cada vez que preguntar o sistema operativo para a memoria,
como podes ver en breve nun conxunto de problemas futuro, tende a levar moito tempo.
Así, minimizando a cantidade de tempo, mesmo se está perdendo un pouco de espazo,
tende a ser unha cousa boa.
>> Pero se lermos a parte final da GetString aquí -
e, de novo, a comprensión cada liña, aquí, non é tan importante hoxe -
notar que, finalmente, chama malloc novo
e aloca exactamente como moitos máis coma el necesita para a cadea
e despois xoga fóra chamando o tapón libre excesivamente grande
se realmente foi dobrado moitas veces.
Entón, en suma, é así que GetString vén traballando todo este tempo.
Todo o que fai é ler un personaxe nun momento novo e de novo e de novo,
e cada vez que precisa un pouco de memoria adicional, el pide ao sistema operativo para el
chamando realloc.
>> Algunha pregunta? Todo ben.
>> Un ataque.
Agora que entendemos punteiros ou polo menos están cada vez máis familiarizado con punteiros,
imos considerar como o mundo enteiro comeza a entrar en colapso
Se vostede non pode defenderse contra os usuarios contraditorio,
persoas que están tentando invadir o seu sistema,
persoas que están tentando roubar o seu software, contornando algúns código de rexistro
que eles poderían ter que escribir dentro
>> Bótalle un ollo neste exemplo aquí, que é só o código C, que ten unha función principal na parte inferior
que chama unha función foo. E o que é pasar foo?
[Alumno] un único argumento. >> [Malan] Un argumento único.
Entón, argv [1], o que significa que a primeira palabra que o usuario introduciu na liña de comandos
logo a.out ou o que quere que o programa é chamado.
Entón foo arriba leva un char *. Pero char * é o que? >> [Alumno] Unha secuencia.
[Malan] Un fío, entón non hai nada novo aquí.
Esta secuencia é arbitrariamente sendo chamado de bar.
Nesta liña aquí, char c [12], nunha especie de semi-técnico inglés, o que é esa liña está facendo?
[Estudante] Unha matriz de - Array >> de? >> [Alumno] personaxes. Personaxes. >>
Déame un conxunto de 12 caracteres. Así, poderiamos chamar iso de un buffer.
É tecnicamente chamado c, pero un tapón na programación significa só unha morea de espazo
que pode poñer algunhas cousas dentro
Entón, por fin, memcpy que non usei antes, pero probablemente pode adiviñar o que fai.
El copia memoria. O que fai?
Ao parecer, copia bar, a súa entrada en C, pero só ata a lonxitude da barra.
Pero hai un erro aquí. >> [Alumno] Debe do carácter sizeof. Ok >>.
Tecnicamente, debemos realmente facer strlen (bar) * sizeof (char)). Isto é correcto.
Pero, no peor caso aquí, imos supor que isto é -
Okay. Despois, hai dous erros.
Entón, sizeof (char));
Imos facelo un pouco máis.
Entón, agora aínda hai un erro, que é o que? >> [Resposta do alumno inaudível]
Asegúrese de que o que? >> [Alumno] Comprobarase NULL.
Nós xeralmente debe ser a verificación de NULL porque as cousas malas suceden
cando o punteiro está NULL porque pode acabar indo alí,
e non debe nunca estar indo NULL por dereferencing co operador estrela.
Entón, iso é bo. E o que máis estamos facendo? Loxicamente, hai unha falla aquí tamén.
[Alumno] Asegúrese de que argc é> = 2.
Polo tanto, comproba que argc é> = 2. Ok, entón hai tres erros neste programa.
Estamos comprobando se o usuario realmente escribiu algo en argv [1]. Bo
Entón, cal é o erro terceiro? Si >> [Alumno] C pode non ser grande abondo.
Bo Nós verificar un escenario.
Nós implicitamente comprobado non copiar máis memoria do que superar a lonxitude da barra.
Entón, se a cadea que o usuario introduciu é de 10 carácteres,
Isto está dicindo só copiar 10 caracteres. E está todo ben.
Pero e se o usuario introduciu unha palabra no poder como unha palabra de 20 caracteres?
Isto está dicindo copia 20 caracteres de bar en que?
C, tamén coñecida como o noso buffer, o que significa que vostede acaba de escribir datos
a 8 lugares de bytes que non ten,
e non ten-los no sentido de que nunca alocados eles.
Polo tanto, este é o que é xeralmente coñecido como o ataque de buffer overflow ou ataque estourido de buffer.
E é un ataque no sentido de que o usuario ou o programa que está chamando a súa función
está facendo iso de forma maliciosa, o que realmente acontece próximo pode ser realmente moi malo.
>> Entón, imos dar un ollo nesta foto aquí.
Esta imaxe representa a súa pila de memoria.
Lembre que cada vez que chamar a unha función que comeza este cadro pouco sobre a pila
e despois outro e despois outro e outro.
E, ata agora, temos só un tipo de abstraídas estes como rectángulos
ou no consello ou na pantalla aquí.
Pero, se aumentar o zoom nun deses rectángulos, cando chamar unha función foo,
verifícase que hai máis no interior da pila de que o cadro en que rectángulo
que só X e Y e a e b, como fixemos fala de intercambio.
Acontece que hai algúns detalles de nivel inferior, entre eles, o enderezo de retorno.
Así, verifícase cando principal chámase foo, principal saber foo
o enderezo principal na memoria do ordenador
porque doutro xeito, así que foo está feito de execución, como neste caso aquí,
unha vez que chegar a esta cinta pechado rizado a finais de foo,
como o diaño non foo sabe onde o control do programa que ir?
Acontece que a resposta a esta pregunta é neste rectángulo vermello aquí.
Isto representa un punteiro, e cabe ao ordenador para almacenar temporalmente
sobre a pila de chamada o enderezo da páxina, de xeito que, unha vez que está feito foo execución,
o ordenador sabe onde e cal liña principal para volver.
Cadro punteiro agás se relaciona de forma semellante a esta.
Char bar * aquí representa o que?
Agora este segmento azul aquí é marco foo. O que é o bar?
Bar é só o argumento para a función foo.
Polo tanto, agora estamos de volta ao tipo de cadro familiar.
Hai máis cousas e máis distraccións na pantalla,
pero ese segmento de luz azul é só o que estamos deseñando no cadro-negro
para algo así como intercambio. Ese é o marco para foo.
E a única cousa que agora é o bar, que é este parámetro.
Pero o que máis debería estar na pila de acordo con este código aquí?
[Alumno] char c [12]. >> [Malan] char c [12].
Tamén debe ver 12 cadrados de memoria alocada para unha variable chamada c,
e de feito temos que na pantalla.
O principio hai c [0], e logo o autor deste diagrama
non se incomodou deseñando as prazas, pero hai de feito hai 12
porque se ollar no ángulo inferior dereito, c [11], se contar de 0 é o byte 12 tal.
Pero aquí está o problema.
En que dirección está crecendo c?
Tipo de arriba abaixo se comeza no principio e crece cara a abaixo.
Non se parece con nós mesmos deixamos pista moi aquí.
Nós tipo de pintado nos en un canto,
e que c [11] é ata contra bar, que está á dereita contra o punteiro de Marco Salvo,
que é ata contra enderezo de retorno. Non hai máis espazo.
Entón, cal é a implicación entón se romper
e intenta ler 20 bytes nun buffer de 12 bytes?
Onde están os 8 bytes máis indo? >> [Alumno] Inside -
Dentro de todo o resto, algúns dos cales é super importante.
E a cousa máis importante, potencialmente, é a caixa vermella alí, enderezo de retorno,
porque supoña que accidentalmente ou adversarially substituír estes 4 bytes,
que o enderezo de punteiro, non só co lixo, pero cun número
que pasa a representar un enderezo real na memoria.
Cal é a implicación, loxicamente? >> [Alumno] Función vai voltar a un lugar diferente.
Exactamente.
Cando retorna foo e hits que chaveta, o programa seguirá
non volver para a principal, que vai volver a calquera enderezo en que é caixa vermella.
>> No caso de rexistro de software evitar,
e se o enderezo que está a ser devolto a é a función que normalmente se chama
despois que pagou para o software e inserido o seu código de rexistro?
Pode clasificar de enganar o ordenador en non ir aquí, pero en vez de ir ata aquí.
Ou se é realmente intelixente, un rival realmente pode escribir no teclado, por exemplo,
non unha palabra real, non 20 personaxes, pero supoño que el ou ela realmente tipos en
algúns personaxes que representan o código.
E non vai ser de código C, que vai de feito ser os personaxes
que representan o código de máquina binaria, 0s e 1s.
Pero supoña que son espertos o suficiente para facelo,
dalgunha forma, pegar no ventá de GetString algo que é esencialmente código compilado,
e os últimos 4 bytes substituír este enderezo de retorno.
E o enderezo é que a entrada de facer?
É realmente almacena neste rectángulo vermello a dirección do primeiro byte do buffer.
Entón ten que ser realmente intelixente, e iso é unha chea de intento e erro para persoas malas aí fóra,
pero se pode descubrir o quão grande é este buffer
de tal forma que os bytes últimos na entrada que fornecer para o programa
ocorrer de ser equivalente ao enderezo do inicio da súa reserva, pode facelo.
Se dicimos normalmente Ola e \ 0, que é o que acaba no buffer.
Pero se somos máis espertos e preenchemos o buffer co que imos chamar xenericamente código de ataque -
AAA, ataque, ataque, ataque - onde iso é só algo que fai algo malo,
Qué acontece se vostede é realmente intelixente, pode facelo.
Na caixa vermella aquí é unha secuencia de números - 80, C0, 35, 08.
Teña en conta que que coincide co número que está aquí enriba.
É na orde inversa, pero máis sobre iso noutro momento.
Teña en conta que este enderezo de retorno foi deliberadamente modificado
para igualar o enderezo aquí, non o enderezo do principal.
Entón, se o cara mal é super intelixente, el ou ela vai incluír nese código de ataque
algo así como eliminar todos os ficheiros do usuario ou copiar as claves
ou crear unha conta de usuario que eu poida entón facer login para - nada.
>> E iso é tanto o perigo e poder de C.
Porque ten acceso a memoria a través de punteiros
e, polo tanto, pode escribir o que queira na memoria dun ordenador,
pode facer un ordenador facer o que quere
simplemente por ter que saltar dentro do seu propio espazo de memoria.
E así ata hoxe tantos programas e tantos sitios que están comprometidas
resumen-se a persoas que toman vantaxe diso.
E iso pode parecer un super ataque sofisticado, pero non sempre é iniciado así.
A realidade é que o que a xente malas normalmente facer é,
se é un programa en liña de comandos ou un programa gráfico ou un sitio web,
acaba de comezar a ofrecer un absurdo.
Escribe unha palabra moi grande no campo de investigación e escriba Intro
e esperar a ver se o sitio traba
ou esperar a ver se o programa se manifesta algunha mensaxe de erro
porque se ten sorte como o cara mal e proporcionar unha información tolo
que traba o programa, isto significa que o programador non anticipou o seu mal comportamento,
o que significa que pode ser con bastante esforzo, estudo bastante e erro,
descubrir como frear un ataque máis preciso.
Así como unha gran parte de seguridade non é só evitar estes ataques completamente
pero detecta-los e realmente ollar os rexistros
e ver o que as persoas tolas entradas escritas na súa páxina web,
o que termos de busca tecleados persoas na súa páxina web
na esperanza de rebosar algúns buffer.
E iso todo se reduce a principios simple do que é unha matriz
eo que iso supón para reservar e utilizar a memoria.
>> Relacionado con iso, entón tamén é este.
Nós só ollar para dentro dun disco duro novo.
Vostede recorda de unha ou dúas semanas que cando arrastrar os ficheiros ao lixo ou lata de lixo,
o que pasa? >> [Alumno] Nada. >> Absolutamente nada, non?
Eventualmente, se executar pouco espazo en disco,
Windows ou Mac OS vai comezar a borrar arquivos para ti.
Pero se arrastrar algo alí dentro, que non é de todo segura.
Todo o seu compañeiro de cuarto ou amigo ou membro da familia ten que facer é premer dúas veces e, listo,
hai todos os ficheiros multimedia que intentou eliminar.
A maioría de nós, polo menos, saber que ten co botón dereito ou prema
e lixo o baleiro ou algo así.
Pero, aínda así, que non chega a facer o truco
porque o que ocorre cando ten un arquivo no seu disco duro
que representa un documento de Word ou algún JPEG, e iso representa o seu disco duro,
e digamos que esta franxa aquí representa o ficheiro,
e está composto de unha morea de 0s e 1s.
O que acontece cando non só arrastrar o ficheiro ao lixo ou lixo
pero tamén baleiralo-la? Especie de nada.
Non hai absolutamente nada agora.
Agora é só nada porque algo ocorre en forma de táboa.
Polo tanto, hai unha especie de base de datos ou táboa dentro da memoria dun ordenador
que, esencialmente, ten unha columna para arquivos dos nomes e unha columna para arquivos 'localización,
onde isto pode ser lugar de 123, só un número aleatorio.
Así, poderiamos ter algo x.jpeg e localización 123.
O que acontece entón cando realmente baleirar o seu lixo?
Que vai.
Pero o que non vai é a 0s e 1s.
>> Entón, cal é entón a conexión pset4?
Ben, con pset4, só porque temos accidentalmente borrados da tarxeta de memoria flash compacto
que todas estas fotos ou só porque pola mala sorte se corrompeu
non significa que os 0s e 1s non aínda están alí.
Quizais algúns deles son perdidos porque algo foi corrompido
no sentido de que algúns convertéronse en 0s e 1s 1s fixo 0s.
Cousas malas poden ocorrer por mor do software de buggy ou hardware defectuosa.
Pero moitos deses bits, quizais ata o 100% deles, aínda están alí.
É que o ordenador ou a cámara non sabe onde comezou JPEG1
e onde JPEG2 iniciado.
Pero se, programador, sabe, con un pouco de habilidade onde os JPEGs son
ou o que parece que poida analizar o JPEG 0s e 1s e dicir, JPEG,
podes escribir un programa con esencialmente só un é ou while
que recupera cada un destes ficheiros.
Así, a lección, entón, é para comezar a xeito seguro de borrar os seus arquivos
Se desexa evitar este completamente. Si
>> [Alumno] Como é que di no seu computador
que ten máis memoria do que fixo antes?
Ter máis memoria do que fixo antes - >> [alumno] Máis memoria dispoñible.
Oh Boa pregunta.
Entón, por que despois de baleirar o lixo do seu ordenador non dicir
que teña máis espazo libre do que fixo antes?
En poucas palabras, porque está mentindo.
Máis tecnicamente, ten máis espazo, porque agora lle dixo
pode pór outras cousas en que o ficheiro xa foi.
Pero iso non significa que os bits están indo aínda que,
e iso non significa que os bits están sendo substituidas para todos 0s, por exemplo,
para a súa protección.
Entón, por outra banda, se seguramente borrar arquivos ou destruír fisicamente o dispositivo,
que realmente é a única forma, por veces, en torno a iso.
>> Entón, por que non deixamos que a nota semi-asustado, e imos velo o luns.
[Aplausos]
>> [CS50.TV]