Dodaj poglavje o rojstnodnevnem problemu.
This commit is contained in:
parent
40e17b1e06
commit
21674c1270
3 changed files with 5052 additions and 3865 deletions
8810
git-obzornik.pdf
8810
git-obzornik.pdf
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
|||
#set page("a4", margin: 20mm, numbering: "1")
|
||||
#set math.equation(numbering: "(1)")
|
||||
#set heading(numbering: "1.")
|
||||
#show heading: block.with(below: 1.5em)
|
||||
#set text(lang: "sl")
|
||||
|
|
@ -35,7 +36,7 @@ je v resnici zelo preprost in njegovo razumevanje nas lahko reši marsikatere za
|
|||
= Kaj je Git?
|
||||
|
||||
#link("https://git-scm.com/")[Git] je kot *časovni stroj* za datoteke. Uporabniku omogoča, da vidi *pretekle različice* datotek,
|
||||
sprememinja datoteke, *brez skrbi, da bi kaj pokvaril* in datoteke *deli z drugimi*. Poleg časovnega stroja je
|
||||
spreminja datoteke, *brez skrbi, da bi kaj pokvaril* in datoteke *deli z drugimi*. Poleg časovnega stroja je
|
||||
Git *razpršeno skladišče datotek*. Omogoča, da datoteke *hkrati ureja več uporabnikov* na različnih računalnikih in
|
||||
kasneje spremembe *združi*.
|
||||
|
||||
|
|
@ -77,24 +78,56 @@ Git repozitorij je vsaka mapa, ki vsebuje podmapo `.git` z zgoraj navedenimi pod
|
|||
|
||||
== Zgoščevalna funkcija
|
||||
|
||||
Git ne shranjuje datotek z običajnimi imeni, ampak za ime uporabi vrednost zgoščevalne funkcije njene vsebine. Vrednosti zgoščevalne funkcije vsebine pravimo _zgostitev_ vsebine.
|
||||
Git uporablja zgoščevalno funkcijo _SHA-1_. Funkcija SHA1 je posebna implementacija zgoščevalne funkcije, ki se uporablja v kriptografiji.
|
||||
|
||||
Naj bo $B$ množica vseh možnih podatkovnih nizov(besedil). Zgoščevalna funkcija _SHA1_ je funkcija
|
||||
Git ne shranjuje datotek z običajnimi imeni, ampak za ime uporabi 160 bitno število (40 mestno število v 16-tiškem zapisu), ki ga izračuna iz vsebine datoteke.
|
||||
Git za izračun imena uporabi _zgoščevalno funkcijo_. Naj bo $B$ množica vseh možnih podatkovnih nizov(besedil), $n$-bitna zgoščevalna funkcija je funkcija
|
||||
$
|
||||
H: B -> {0, 1, dots, 2^(160)-1},
|
||||
H: B -> {0, 1, dots, 2^(n)-1},
|
||||
$
|
||||
ki vsakemu besedilu $b$ priredi 160-bitno zgostitev besedila $H(b)$. Funkcija $H$, je izbrana tako, da
|
||||
ki vsakemu besedilu $b$ priredi $n$-bitno vrednost $H(b)$. Vrednosti zgoščevalne funkcije $H(b)$ pravimo _zgostitev_ vsebine $b$. Funkcija $H$, je izbrana tako, da
|
||||
sprememba enega samega bita v besedilu $b in B$ spremeni vrednost $H(b)$. Poleg mora dobra zgoščevalna funkcija zagotoviti, da je porazdelitev vrednosti $H(b)$ čim bližje enakomerni porazdelitvi. To pomeni, da so vse vrednosti $H(b)$ približno enako verjetne.
|
||||
Kljub temu, da zgoščevalna funkcija $H$
|
||||
ni injektivna, je verjetnost, da bi imela dva podatkovna niza isto zgostitev (vrednost $H$) zelo majhna($approx 2^(-159)$). Zato lahko v praksi predpostavimo, da je niz $b$ enolično določen z njegovo zgostitvijo $H(b)$.
|
||||
|
||||
Ko datoteko z vsebino $b$ zabeležimo v Git repozitorij, git shrani vsebino v datoteko z imenom $H(b)$ v `git/objects`#footnote[V resnici Git shrani vsebino v datoteko z imenom $h_3 h_4 dots h_(40)$ v mapi $h_1 h_2$, kjer je
|
||||
Git uporablja zgoščevalno funkcijo _SHA1_. Funkcija SHA1 je posebna implementacija zgoščevalne funkcije, ki se je uporabljala v kriptografiji#footnote[Leta 2017 so raziskovalci
|
||||
iz CWI Amsterdam in Google Research našli prvi praktični primer dveh različnih pdf datotek, ki imata isto SHA1 zgostitev#cite(<stevens_first_2017>). Opisan napad so poimenovali _SHAttered_. Git je zato z verzijo `v2.13.0`
|
||||
začel uporabljati verzijo SHA1, ki je odporna proti napadu _SHAttered_. Kljub temu razvijalci Gita načrtujejo, da bodo SHA1 postopoma nadomestili z ].
|
||||
|
||||
Ko datoteko z vsebino $b$ zabeležimo v Git repozitorij, Git izračuna zgostitev vsebine $H(b)$ in jo shrani v datoteko z imenom $H(b)$ v `git/objects`#footnote[V resnici Git shrani vsebino v datoteko z imenom $h_3 h_4 dots h_(40)$ v mapi $h_1 h_2$, kjer je
|
||||
$h_1 h_2 h_3 dots h_(40)$ zapis $H(b)$ v 16-tiškem sistemu. Datoteka, katere vsebina ima zgostitev $H(b)$ enako `8dd6d4bdaeff93016bd49474b54a911131759648` bo shranjena v `.git/objects/8d/d6d4bdaeff93016bd49474b54a911131759648`].
|
||||
Vsebina $b$ je tako vedno dostopna pod imenom, ki je enako njeni zgostitvi $H(b)$. Tako dobimo #link("https://en.wikipedia.org/wiki/Content-addressable_storage")[vsebinsko naslovljivo shrambo objektov], ki je ena od bistvenih značilnosti Gita. Ta način shranjevanja omogoča, da lahko vedno preverimo, če ima shranjenjena vsebina isto zgostitev, kot je njeno ime. Lahko tudi shranimo več različic iste datoteke, saj ima vsaka različica drugačno zgostitev. Zgostitev služi tudi kot kontrola, če je prišlo do kvaritve podatkov, ki so shranjeni v Git repozitoriju.
|
||||
|
||||
Podrobnosti o tem, kako Git hrani podatke, si lahko preberete v knjigi Pro Git
|
||||
#cite(<chacon_102_nodate>, supplement: [pog. 10.2]).
|
||||
=== Kolizije zgostitev in rojstnodnevni paradoks
|
||||
|
||||
Git hrani datoteke pod imeni, ki so enaka zgostitvi vsebine. Kaj pa če imata dve različni vsebini isto zgostitev. Funkcija $H$ ni injektivna, saj je množica nizov, bistveno večja od množice zgostitev. To pomeni, da imata lahko dve različni datoteki enako zgostitev. Če bi prišlo do tega, bi Git shranil le eno datoteko, za drugo pa bi predpostavil da je že shranjena. Na srečo je verjetnost, da bi se kaj takega zgodilo izjemno majhna. Kljub temu, da zgoščevalna funkcija $H$
|
||||
ni injektivna, je verjetnost, da bi imela dva naključno izbrana podatkovna niza isto zgostitev (vrednost $H$) zelo majhna. Zato Git predpostavi, da je niz $b$ enolično določen z njegovo zgostitvijo $H(b)$. Kako bi ocenili verjetnost, da pride do kolizije zgostitev?
|
||||
|
||||
Koliko datotek bi morali shraniti v Git, da bi z znatno verjetnostjo prišlo do kolizije? Vprašanje je povezano z rojstnodnevnim problemom. Kako velika naj bo skupina ljudi,
|
||||
da bo vsaj $50%$ verjetnost, da imata dve osebi na isti dan rojstni dan? Velikost skupine je presenetljivo majhna(23), zato rojstnodnevnei problem včasih poimenujemo paradoks.
|
||||
Vprašanje lahko matematično zastavimo tako. Naključno izberemo $n<d$ števil iz množice ${1, 2, dots, h}$, tako da je vsaka izbira enakomerno porazdeljena. Kolikšna je verjetnost $p(n, h)$, da bosta vsaj dve števili enaki? Verjetnost $p(n, h)$ izračunamo elementarno z verjetnostjo nasprotnega dogodka:
|
||||
|
||||
$
|
||||
1 -p(n, h) = (h dot (h-1) dots.c (h-n+1))/(h^n) = product_(k=1)^(n-1)(1-k/h).
|
||||
$
|
||||
|
||||
Če izraz logaritmiramo, dobimo
|
||||
$
|
||||
log(1 - p(n, h)) = sum_(k=1)^(n-1)log(1-k/h) < -sum_(k=1)^(n-1) k/h=-(n(n-1))/(2h).
|
||||
$<eq_log_ocena>
|
||||
Res! Logaritem je konveksna funkcija, zato so vrednosti manjše od vrednosti na tangenti $log(1-k/h) = log(1-x) < x = k/h$.
|
||||
|
||||
Od tod izpeljemo oceno za $p(n, h)$
|
||||
$
|
||||
p(n, h) > 1 - e^(-(n(n-1))/(2h)) approx 1 - e^(-n^2/(2h)).
|
||||
$<eq_ocena>
|
||||
Za vrednosti $1 << n << h$ je $1- e^(-n^2/(2h))$ tudi dobra aproksimacija za $p(n, h)$.
|
||||
|
||||
Da bi odgovorili kako odporna je zgoščevalna funkcija na morebitne kolizije, moramo rešiti obratno nalogo: največ koliko števil $n(p, d)$ lahko izberemo, da bosta med izbranimi števili vsaj dve enaki z verjetnostjo manjšo od $p in [0,1]$. Natančen odgovor na to vprašanje ni tako preprost #cite(<brink_probably_2012>). Lahko pa uporabimo oceno (@eq_ocena) in čez palec ocenimo:
|
||||
|
||||
$
|
||||
-n^2 approx log(1-p) =>\ n(p, h) approx sqrt(2h log(1/(1-p))) approx sqrt(2h).
|
||||
$
|
||||
|
||||
Funkcija $sqrt(log(1/(1-p)))$ zelo počasi narašča, ko se $p$ približuje $1$, zato jo lahko zanemarimo. Če je zgoščevalna funkcija $160$ bitna, kot je primer za SHA1, je
|
||||
$n approx sqrt(2^(160)) approx 2^(80)$. Znatna verjetnost, da pride do kolizije zgostitev, bi se pojavila, ko bi shranili $2^(80)$ različnih datotek v Git.
|
||||
Raziskovalci, ki so razvili napad _SHAttered_, pa so potrebovali zgolj približno $2^(63)$ primerov, da so prišli do kolizije.
|
||||
|
||||
== Datotečna drevesa
|
||||
|
||||
|
|
@ -139,7 +172,7 @@ datotek enaka(npr. `bla.txt` in `mapa/bla.txt`), Git shrani le eno kopijo, ki je
|
|||
#let bla(coord, ..args) = file-object(coord, "bcc138", ..args)[bla]
|
||||
#let blabla(coord, ..args) = file-object(coord, "2ce22b", ..args)[blabla]
|
||||
|
||||
#figure(caption: [Primer datotečnega grafa povezanega z zgostitvami],
|
||||
#figure(caption: [Primer datotečnega grafa povezanega z zgostitvami. Zaradi preglednosti smo izpisali le prvih 6 znakov zgostitve.],
|
||||
diagram(
|
||||
{
|
||||
bla((-1, 1), name:<bla>)
|
||||
|
|
@ -165,6 +198,10 @@ posamezen objekt v Gitu preprosto zgostitev(angl. hash) vsebine tega objekta. Po
|
|||
vsebina objekta določena z njegovo zgostitvijo. To pomeni, da lahko enostavno preverimo verodostojnost vsebine, ki je shranjena v Gitu. Git hrani skladišče objektov v mapi `.git/objects`.
|
||||
|
||||
]
|
||||
|
||||
|
||||
Podrobnosti o tem, kako Git hrani podatke, si lahko preberete v knjigi Pro Git
|
||||
#cite(<chacon_102_nodate>, supplement: [pog. 10.2]).
|
||||
= Zgodovinski graf sprememb
|
||||
|
||||
V prejšnjem poglavju smo videli, kako Git hrani vsebino celotne mape in kako je mogoče do vsebine dostopati če poznamo zgostitvijo korenskega mape. Zgodovinsko drevo sprememb je preprosta razširitev omenjene podatkovne strukture.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,28 @@
|
|||
|
||||
@inproceedings{stevens_first_2017,
|
||||
address = {Cham},
|
||||
title = {The {First} {Collision} for {Full} {SHA}-1},
|
||||
isbn = {978-3-319-63688-7},
|
||||
abstract = {SHA-1 is a widely used 1995 NIST cryptographic hash function standard that was officially deprecated by NIST in 2011 due to fundamental security weaknesses demonstrated in various analyses and theoretical attacks.},
|
||||
booktitle = {Advances in {Cryptology} – {CRYPTO} 2017},
|
||||
publisher = {Springer International Publishing},
|
||||
author = {Stevens, Marc and Bursztein, Elie and Karpman, Pierre and Albertini, Ange and Markov, Yarik},
|
||||
editor = {Katz, Jonathan and Shacham, Hovav},
|
||||
year = {2017},
|
||||
pages = {570--596},
|
||||
}
|
||||
|
||||
@misc{vuk_git-intro_nodate,
|
||||
title = {git-intro},
|
||||
url = {https://git.fri.uni-lj.si/martin.vuk/git-intro},
|
||||
abstract = {Short introduction to Git},
|
||||
language = {en-US},
|
||||
urldate = {2026-01-03},
|
||||
journal = {git-intro},
|
||||
author = {Vuk, Martin},
|
||||
file = {Snapshot:/home/martinv/Zotero/storage/3V3R4YCH/git-intro.html:text/html},
|
||||
}
|
||||
|
||||
@incollection{chacon_102_nodate,
|
||||
title = {10.2 {Git} {Internals} - {Git} {Objects}},
|
||||
url = {https://git-scm.com/book/en/v2/Git-Internals-Git-Objects},
|
||||
|
|
@ -7,11 +31,17 @@
|
|||
author = {Chacon, Scott and Straub, Ben},
|
||||
}
|
||||
|
||||
@misc{vuk_git-intro_nodate,
|
||||
title = {Uvod v Git},
|
||||
url = {https://git.fri.uni-lj.si/martin.vuk/git-intro},
|
||||
abstract = {Uvod v Git},
|
||||
language = {en-US},
|
||||
journal = {git-intro},
|
||||
author = {Vuk, Martin},
|
||||
@article{brink_probably_2012,
|
||||
title = {A (probably) exact solution to the {Birthday} {Problem}},
|
||||
volume = {28},
|
||||
issn = {1572-9303},
|
||||
url = {https://doi.org/10.1007/s11139-011-9343-9},
|
||||
doi = {10.1007/s11139-011-9343-9},
|
||||
abstract = {Given a year with n≥1 days, the Birthday Problem asks for the minimal number such that in a class of students, the probability of finding two students with the same birthday is at least 50 percent. We derive heuristically an exact formula for and argue that the probability that a counter-example to this formula exists is less than one in 45 billion. We then give a new derivation of the asymptotic expansion of Ramanujan’s Q-function and note its curious resemblance to the formula for .},
|
||||
number = {2},
|
||||
journal = {The Ramanujan Journal},
|
||||
author = {Brink, David},
|
||||
month = jun,
|
||||
year = {2012},
|
||||
pages = {223--238},
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue