Harjoitustehtävät 10
Osaamistavoitteet
Tämän harjoituksen päätteeksi
- tunnet, mitä rekursio on ja miten tehdään rekursiivinen funktio
- osaat soveltaa silmukoita ja dynaamisia tietorakenteita paremmin
- olet tutustunut poikkeuksiin (Exception) ja poikkeusten käsittelyyn
T0. Palaute tästä osasta (0,5 p.)
Auta meitä parantamaan tätä kurssia antamalla palautetta tästä kurssin osiosta.
Huom: Vastaa tähän vasta, kun olet valmis tämän harjoitustehtäväkerran tehtävien kanssa
Vastaa alla oleviin kohtiin tämän kurssin osasa käsiteltyjen materiaalien ja tehtävien (luennot, esimerkit, kurssimoniste, harjoitustehtävät) perusteella.
Saat 0,25 pistettä vastaamalla kaikkiin alla oleviin väittämiin.
Kirjoita arvio tällä viikolla käyttämästäsi työmäärästä. Laske työmäärään mukaan kaikki tällä viikolla käyttämäsi aika: lähiopetukseen osallistuminen, oppimateriaalin lukeminen, harjoitustehtävien tekeminen, luentovideon katsominen, tehtävien purkutilaisuuteen osallistuminen ja niin edelleen.
Kertaustehtävät
Voit halutessasi palautella mieleen asioita tekemällä kertaustehtäviä. Luonnollisesti voit ohjauksessa myös pyytää tukea näiden(kin) tehtävien tekemiseen.
T1. Tulosta numeroita rekursiolla (1 p.)
Lue ensin monisteesta: 22. Rekursio.
Katso video: Luento 17 (kevät 2024): Rekursio.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio, ei class- eikä Main-koodia.
Arviointi: Tehtävässä on automaattinen arvostelu. Oikeasta tulosteesta yllä olevan mallin perusteella 1 p.
T2. Summaa numeroita rekursiolla (1 p.)
Lue ensin monisteesta: 22. Rekursio.
Katso video: Luento 17 (kevät 2024): Rekursio.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio ja testit, ei class- eikä Main-koodia.
Arviointi: Tehtävässä on automaattinen arvostelu. Oikeasta tulosteesta yllä olevan mallin perusteella 1 p.
T3. Laske merkit rekursiolla (1 p.)
Lue ensin monisteesta: 22. Rekursio.
Katso video: Luento 17 (kevät 2024): Rekursio.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Tee funktio LaskeMerkit, joka palauttaa halutun merkin esiintymien määrän merkkijonossa. Jos etsitään aakkosta, tulee mukaan laskea sekä suur- että pienaakkoset.
Funktio tulee toteuttaa käyttäen rekursiota, silmukkarakenteita ei saa käyttää.
Esimerkki funktion toiminnasta:
Ohjelmassa on valmiina luokka, ja lisäksi pääohjelma jota et näe (ks. Näytä koko koodi). Palautuslaatikkoon tulee kirjoittaa ainoastaan pyydetty funktio.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio ja testit, ei class- eikä Main-koodia.
Arviointi: Tehtävässä on automaattinen arvostelu. Oikeasta tulosteesta yllä olevan mallin perusteella 1 p.
Saat otettua merkkijonosta osan Substring-metodilla. Esimerkiksi
string mjono = "Kolme miestä istuu saunassa";
string kaikkiPaitsiEka = mjono.Substring(1);
// kaikkiPaitsiEka on nyt "olme miestä istuu saunassa"Vaihtoehtoisesti voit ottaa merkkijonosta kaiken paitsi viimeisen merkin:
string mjono = "Kolme miestä istuu saunassa";
string kaikkiPaitsiVika = mjono.Substring(0, mjono.Length - 1);
// kaikkiPaitsiVika on nyt "Kolme miestä istuu saunass"Lisätietoa kiinnostuneille: Voit Substringin sijaan käyttää ns. range indexer -ominaisuutta. Saman tapainen "oikotie" on yleistynyt viime vuosina monissa kielissä. Esimerkiksi:
T4*. Lottorivin arpominen (1 p.)
Lue ensin monisteesta: 23. Dynaamiset tietorakenteet.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Tee Lotto-niminen funktio, joka arpoo ja tulostaa 7 numeroa ja 3 varanumeroa 40:stä.
Funktiota kutsutaan pääohjelmasta ilman argumentteja.
Funktion antaman tulosteen tulisi näyttää tältä:
Onnennumerot: 17 10 6 25 30 12 24
Lisänumerot: 9 20 13
Funktion ei tarvitse palauttaa mitään arvoa.
Palautuslaatikossa on valmiina pieni pätkä valmista koodia. Täydennä funktio.
Palautuslaatikon koodissa (klikkaa Näytä koko koodi) on lisäksi valmiiksi mukana apufunktio Sekoita, joka sekoittaa parametrina annettun listan alkioiden paikkoja. Voit käyttää kyseistä apufunktiota avuksi.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio, ei class- eikä Main-koodia.
Arviointi: Tehtävässä on automaattinen arvostelu. Oikeasta tulosteesta yllä olevan mallin perusteella 1 p.
T5-6. Salasanan generointi (2 p.)
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Tee funktio GeneroiSalasana. Funktio ottaa parametreina ainakin seuraavat tiedot:
- salasanan pituus (
int), - voiko salasana sisältää suuraakkosia (
A-Z) (bool), - voiko salasana sisältää numeroita (
0-9) (bool), - voiko salasana sisältää erikoismerkkejä (
!@#$%&-) (bool)
Funktio palauttaa salasanan näiden parametrien perusteella.
Erikoismerkkejä ovat:
!@#$%&-
Muita erikoismerkkejä ei tässä oteta huomioon.
Esimerkki funktion toiminnasta:
// Luodaan satunnaislukuolio
Random r = new Random();
// Generoidaan satunnainen salasana, joka täyttää seuraavat ehdot:
// - 10 merkkiä pitkä
// - voi sisältää suuraakkosia (A-Z)
// - voi sisältää numeroita (0-9)
// - voi sisältää erikoismerkkejä (!@#$%&-)
string salasana = GeneroiSalasana(r, 10, true, true, true);
Console.WriteLine(salasana); // Voisi palauttaa **esimerkiksi** `pV30b5E!o1`Palautus: Palautuslaatikkoon palautetaan koko ohjelma, mukaan lukien luokka ja pääohjelma.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos teit tehtävän mielestäsi täysin oikein, 2 piste, puoliksi oikein 1 piste jne.
Vinkkejä:
- Tarvitset ohjelmassasi satunnaisuutta käyttäen Random-oliota. Esimerkiksi luvun arpominen väliltä 0-9 onnistuu seuraavasti.
- Kirjaimen arpominen: (1) Luo sopivista pienaakkosista yksi pitkä merkkijono, (2) arvo
Random-olionNext-metodin avulla kokonaisluku väliltä [0, ... merkkijonon pituus], ja (3) ota merkkijonosta kirjain arpomasi luvun mukaisesta indeksistä. - Erikoismerkin arpominen: Samoin näistä kannattaa tehdä yksi merkkijono ja arpoa siitä yksi.
- "Kolikon heiton" (esim. tuleeko yksittäisen kirjaimen olla suuraakkonen vai ei) saat toteutettua esimerkiksi käyttämällä Random-olion NextDoublea, joka antaa desimaaliluvun väliltä 0-1:
Huomautus 1: Useiden Random-olioiden luomista pitäisi C#:n dokumentaation mukaan välttää. Niinpä jos haluat generoida salasanoja silmukassa (esimerkiksi pääohjelmassa), tulee Random-olio r luoda yhden kerran koko ohjelmassa (pääohjelman aluksi) ja antaa sitten r argumenttina, sillä muuten arpominen ei käytännössä onnistu. Luonnollisesti Random-olio pitää tällöin lisätä funktion esittelyriville parametrilistaan ensimmäiseksi. Esimerkki pääohjelmasta (voit copy-pastettaa tämän itsellesi):
Random random = new Random();
for (int i = 0; i < 10; i++)
{
Console.WriteLine(GeneroiSalasana(r, 10, true, true, true));
}Huomautus 2: Olisi hyvä arvioida, kuinka todennäköisiä kunkin merkin esiintyminen on. Esimerkiksi ovatko kaikki merkit yhtä todennäköisiä, vai onko tietty merkki yhtä todennäköisesti (a) kirjain, (b) numero tai (c) erikoismerkki? Tähän ei ole yhtä ja oikeaa vastausta.
T7. Poikkeusten käsittely (1 p.)
Lue ensin monisteesta: 24. Poikkeukset.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Täydennä funktio MuutaJono(String s, double oletus) siten, että alla olevassa palautuslaatikossa oleva pääohjelma toimii.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio ja testit, ei class- eikä Main-koodia. Pääohjelma on jo TIM-versiossa valmiiksi mukana.
Arviointi: Tehtävässä on automaattinen arvostelu. Jos vastaus kääntyy ja tulostus vastaa Main-aliohjelmassa olevaa mallia, 1 p.
Kun toteutat funktiota MuutaJono, käytä hyväksi Double-luokan funktiota Double.Parse ja sitä, että jos muuttaminen ei onnistu, Parse heittää poikkeuksen.
Huomautus: Jos kotikoneesi asetukset ovat suomalaisittain, Double.Parse-metodi olettaa argumentin erotinmerkiksi pilkun. Timissä erotinmerkkinä on piste. Jos haluat omalle koneellesi pisteen erotinmerkiksi, laita Parse-metodin argumentiksi System.Globalization.CultureInfo.InvariantCulture:
Tämä funktio yrittää siis poimia annetusta merkkijonosta liukuluvun (double) ja palauttaa sen. Mikäli tämä ei onnistu, palauttaa se oletusarvon. Funktiolle on oikeassa elämässä käyttöä koska käyttäjältä saatu syöte on aina merkkijono ja se pitää pystyä muuttamaan reaaliluvuksi laskemista varten. Tuo desimaalierotin on vaikeampi. Parse käyttää sitä erotinta, mikä on järjestelmään asetettu. Oikeasti pitäisi siis vielä osata tulkita oikealla tavalla riippumatta siitä, antaako käyttäjä pilkun vai pisteen. Tässä tehtävässä tuosta ongelmasta ei tarvitse välittää vaan riittää yllä olevaan esimerkkiin käsin vaihtaa piste pilkun tilalle jos järjestelmässäsi on piste desimaalierottimena (C#-koodin vakioissahan se on aina piste).
T8. Testaa kaksi aliohjelmaa (1 p.)
Lue ensin monisttesta: 11. Testaaminen
Tarkista vähintään kahden tämän harjoituskerrassa tehdyn aliohjelman toimintaa automaattisella testillä ComTest-työkalua käyttäen.
Huomaa, että ohjelmia, joissa on pelkkä Main-pääohjelma, ei voida tämän kurssin tiedoilla testata, kuten ei myöskään Jypeli-pelejä. Siksi testaamista tehdään harjoitustehtävissä vain static-aliohjelmille, jotka palauttavat jonkun arvon.
On suositeltavaa käyttää ComTest-työkalua Riderin kautta. Pääset eteenpäin seuraavilla ohjeilla:
Palautus: Kerro, minkä tehtävän ja minkä aliohjelman/aliohjelmien toiminnan testasit.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-1. Jos teit tehtävän mielestäsi täysin oikein, 1 piste, puoliksi oikein 0.5 pistettä jne.
Taulukon testaaminen Comtestilla:
Jos haluat viedä testiin taulukon ilman, että luot apumuuttujaa, niin tee seuraavasti.
Katso miten 2-ulotteista taulukkoa voidaan testata täältä.
StringBuilderin arvon testaaminen pitää suorittaa ToString()-metodin avulla
V1. ViLLE (1 p.)
Tee ViLLE-tehtävät: 8.1-8.5.
Muista ViLLEn käyttöohje.
B1-2. Pallopuu rekursiolla (2 p.)
Lue ensin monisteesta: 22. Rekursio.
Katso video: Luento 17 (kevät 2024): Rekursio.
Jos haluat tehdä tehtävän Riderissa: Jypeli-tehtävien tekeminen Riderissa.
Tee alla olevaa mallikoodia muokaten ohjelma, joka piirtää kuvan kaltaisen puun rekursiivisesti.
Lopputuloksen pitäisi näyttää täältä:

Halutessasi voit katsoa seuraavaa apumateriaalia:
- Sierpinskin kolmion piirtäminen.
- Tämä tehtävä on osin lähellä ns. fraktaalipuuta (engl. fractal canopy). Verkosta löytyy paljon esimerkkejä sellaisten piirtämisestä.
Palautus: Palautuslaatikkoon palautetaan peliluokan sisältö, eli Begin- ja muut aliohjelmat. Peliluokka on TIM-versiossa valmiiksi mukana (ks. Näytä koko koodi -linkki palautuslaatikossa).
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos teit tehtävän mielestäsi täysin oikein, 2 pistettä, puoliksi oikein 1 piste jne.
Beginissä: Hyvä alkukulma piirtämiseen on vaikkapa Math.PI / 2. Pallon säteeksi voit antaa vaikka 100.
Pallo-aliohjelmassa: Kokeile vaihdella suuntaa ja sädettä muuttavia vakioita ja katso miten ne vaikuttavat kuvaan.
B3-4. Valuuttakurssien haku (2 p.)
Lue ensin monisteesta: 25. Tietojen lukeminen ulkoisesta lähteestä.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Avaa sivu ja klikkaa sivun "Csv-tiedosto". Huomaa että sivu antaa kuitenkin .xls tiedoston nappulan tekstistä huolimatta. Tästä ei tarvitse erityisesti välittää. Muuta tiedoston nimeksi valuutat.xls.
Tiedosto näyttää kutakuinkin tältä
EUR,000001.000000,000001.000000,000001.000000,23/03/2023,08:00
USD,000001.090550,000001.067100,000001.114000,23/03/2023,08:00
JPY,000142.624000,000139.552000,000145.696000,23/03/2023,08:00
Tee uusi konsoliprojekti ja lisää projektiisi tämä tiedosto klikkaamalla projektin nimen päällä hiiren kakkosnäppäimellä Add > Existing Item). Laita tiedosto myös kopioitumaan bin-hakemistoon klikkaamalla tiedoston päällä hiiren oikealla > Properties > Copy to output directory > Always copy.
Poista sitten projektisi lähdekooditiedostosta kaikki sisältö ja liitä tilalle tämän palautuslaatikon pohjakoodi (voit käyttää palautuslaatikossa olevaa Copy-painiketta kaiken koodin kopioimiseksi leikepöydälle).
Tee aliohjelma KyseleValuuttoja, joka kysyy silmukassa käyttäjältä valuuttatunnuksen, ja sitten tulostaa annetun valuutan tiedot ruudulle hieman mukavammin muotoiltuna.
Ohjelman tulisi toimia suunnilleen seuraavasti:
Anna valuutta >USD
USD: Keskikurssi 1.09055. Myynti 1.0671. Osto 1.114. (23/03/2023)
Anna valuutta >JPY
JPY: Keskikurssi 142.624. Myynti 139.552. Osto 145.696. (23/03/2023)
Ohjelma päättyy, kun käyttäjä antaa tyhjän syötteen.
Palautus: Palautuslaatikkoon palautetaan koko ohjelma, mukaan lukien luokka ja pääohjelma. Huom: TIMin palautuslaatikkoon on valmiiksi haettu valuutat.xls (päivitetty viimeksi 31/10/2025, 07:00). Palautuslaatikkoon palautetaan vain ohjelman lähdekoodi.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos teit tehtävän mielestäsi täysin oikein, 2 pistettä, puoliksi oikein 1 piste jne.
Voit muuntaa luvut merkkijonosta liukuluvuikso double.Parse-aliohjelmalla jolloin ylimääräisiä nollia ei näytetä.
Huomautus: Jos kotikoneesi asetukset ovat suomalaisittain, double.Parse olettaa argumentin erotinmerkiksi pilkun. Timissä erotinmerkkinä on piste. Jos haluat omalle koneellesi pisteen erotinmerkiksi, laita Parse-metodin argumentiksi System.Globalization.CultureInfo.InvariantCulture:
B5-6. Binomikerroin (2 p.)
Lue ensin monisteesta: 16. Toistorakenteet.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Erilaisten 7 numeroa sisältävien lottorivien määrä saadaan binomikertoimen kaavasta:
Lisätietoja: https://fi.wikipedia.org/wiki/Kombinaatio.
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio ja testit, ei class- eikä Main-koodia. Pääohjelma on jo TIM-versiossa valmiiksi mukana.
Arviointi: Koodin ajamisesta Aja -painikkeella ja oikeasta tulosteesta 1,5 p; onnistuneesti ajetuista testeista Aja omat testit -painikkeella 0,5 p.
Huomaa, että binomikerrointa ei voi laskea keskimmäisestä kaavasta koska
ylittäisi reilusti pitkienkin
long-kokonaislukujen lukualueen.
Sen sijaan "avattu" muoto on toteutettavissa pelkästään kerto- ja jakolaskuilla sekä silmukoilla.
Vastaus saattaa olla nätimpi, jos avuksi kirjoittaa yhden pienen aliohjelman.
B7. Binomikerroin BigInteger-tyypillä (1 p.)
Lue ensin monisteesta: 16. Toistorakenteet.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Tutki miten C#:issa toimii BigInteger-luokka ja tee Tehtävän B5-6 funktio BigInteger NYliK(int n, int k) sen avulla.
Tee siis Tehtävää B5-6 vastaava toteutus erityyppisellä kokonaislukutyypillä. BigInteger luokan käyttö vaatii, että lisäät seuraavan using-määreen ohjelman alkuun (ellei se ole jo siellä):
Palautus: Palautuslaatikkoon palautetaan pelkkä funktio ja testit, ei class- eikä Main-koodia. Pääohjelma on jo TIM-versiossa valmiiksi mukana.
Arviointi: Koodin ajamisesta Aja -painikkeella ja oikeasta tulosteesta 0,6 p; onnistuneesti ajetuista testeista Aja omat testit -painikkeella 0,4 p.
G1-2. Valuuttakurssien haku verkosta (2 p.)
Lue ensin monisteesta: 25. Tietojen lukeminen ulkoisesta lähteestä.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Tutki miten C#:ssa voidaan lukea syötettä WWW-osoitteesta ja tee Tehtävä B1-2 niin, että valuuttatiedot haetaan suoraan netistä.
Voit lukea tiedostoa osoitteesta
https://tim.jyu.fi/files/kurssit/tie/itkp102/demot/demo10/valuutat.xls
Palautus: Palautuslaatikkoon palautetaan koko ohjelma, mukaan lukien luokka ja pääohjelma.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos teit tehtävän mielestäsi täysin oikein, 2 pistettä, puoliksi oikein 1 piste jne.
G3-4. Pienimmän neliösumman sovitus (2 p.)
Jos haluat tehdä tehtävän Riderissa: Jypeli-tehtävien tekeminen Riderissa.
Pienimmän neliösumman sovitus (PNS-sovitus) on eräs tapa laskea eräänlainen "keskiluku" tai trendi kaksiulotteiselle aineistolle.
Esimerkiksi meillä on havaintopisteitä , joiden periaatteessa pitäisi muodostaa "suora". Laskemalla PNS-suoran kertoimet
ja
voimme piirtää aineistoa parhaiten kuvaavan suoran kaavalla
:
Katso kertoimien laskukaavat (MathWorld, kaavat 12 ja 14).
Tee Jypeli-ohjelma, joka piirtää aineiston ja sitä kuvaavan PNS-suoran.
Alla olevassa palautuslaatikossa on pohjatiedosto, jossa on valmiiksi toimintoja pisteiden lisäämiseksi kentälle. Suora piirretään Paint-aliohjelmassa kutsumalla canvas.DrawLine-metodia (katso TODO-kommentti koodissa).
Palautus: Palautuslaatikkoon palautetaan koko peliluokka, mukaan lukien using-määreet ja luokkamäärittely.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos teit tehtävän mielestäsi täysin oikein, 2 pistettä, puoliksi oikein 1 piste jne.
G5-6. Euler problem 67 (2 p.)
Lue ensin monisteesta: 22. Rekursio.
Katso video: Luento 17 (kevät 2024): Rekursio.
Jos haluat tehdä tehtävän Riderissa: Komentorivitehtävien tekeminen Riderissa.
Ratkaise Euler problem 67. Laskun pitää mennä alle minuuttiin.
Palautus: Palautuslaatikkoon palautetaan koko ohjelma, mukaan lukien luokka ja pääohjelma.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-2. Jos ohjelmasi toimii, 1 piste. Jos ohjelmasi toimii erittäin nopeasti (luokkaa millisekunteja), anna itsellesi 2 pistettä.
Vinkki: katso kevään 2024 luento 17, jossa käydään läpi hieman helpompi Euler problem 18.
G7-11. Steganografia (5 p.)
Jos haluat tehdä tehtävän Riderissa: Jypeli-tehtävien tekeminen Riderissa.
Tee funktio (ja tarvittavat apufunktiot) joilla saat salakirjoitettua merkkijonon Jypelin Image-kuvaan siten, että viesti koodataan kunkin värikomponentin (r, g, b, a) kahteen vähiten merkitsevään bittiin. Tee myös funktio jolla saat luettua viestin tällaisesta kuvasta.
Voit olettaa, että viesti tulee 8-bittisinä merkkeinä. Char-merkin 8 vähiten merkitsevää bittiä saat otettua sanomalla int lowerBits = myChar & 0xff; Tämä riittää ihan hyvin esim. englannin ja suomen kieleen. Toki erikoisemmat merkit jäävät tällä tavalla pois.
Palautus: Palautuslaatikkoon palautetaan koko peliluokka, mukaan lukien using-määreet ja luokkamäärittely.
Arviointi: Käytä Set custom points -toimintoa TIMissa. Tee itsearvio pistemäärästäsi ja syötä omat pisteesi väliltä 0-5. Jos saat onnistuneesti salakirjoitettua viestin kuvaan, laita 3 p. Jos lisäksi saat onnistuneesti luettua viestin kuvasta, laita 2 p lisää.
Olkoon meillä kuvapikseli, jonka värikomponentit ovat
desimaalilukuina:
r=63, g=51, b=25, a=255
binäärilukuina:
r=00111111, g=00110011, b=00011001, a=11111111.
Sovitaan, että meidän koodattava merkki on M (desimaalilukuna 77, bittiesitys 01001101) niin salakirjoituksen tuloksena kuvapikselin uudet väriarvot ovat:
r=00111101 (M-kirjaimen kaksi eniten merkitsevää bittiä on 01, jotka
asetetaan tämän värikomponentin kahdeksi oikeanpuolimmaiseksi bitiksi)
g=00110000 (M-kirjaimen kaksi seuraavaa bittiä on 00)
b=00011011 (jatketaan vastaavasti, bitit 11)
a=11111101 (jatketaan vastaavasti, bitit 01)
Image-kuvan saat byte-taulukoksi (luvut väliltä 0..255) sanomalla kuva.GetByteArray().
Extension-metodi Image-luokkaan, joka asettaa byte-taulukon arvot suoraan kuvapikseleiksi. Tämä löytyy Jypelin versiosta 8.1.0 alkaen, mutta mikäli sinulla on käytössä vanhempi versio, lisää alla oleva projektiisi mukaan. Kutsu tätä sanomalla kuva.SetData(munByteArray, korkeus, leveys);
namespace Jypeli
{
public static class ImageExtension
{
public static void SetData(this Image image, byte[] salakirjoitettu, int kuvanKorkeus, int kuvanLeveys)
{
Color[,] salakirjoitettuColor = new Color[kuvanKorkeus, kuvanLeveys];
for (int i = 0; i < kuvanKorkeus; i++)
{
for (int j = 0; j < kuvanLeveys; j++)
{
int r = salakirjoitettu[4 * (i * kuvanLeveys + j) + 0];
int g = salakirjoitettu[4 * (i * kuvanLeveys + j) + 1];
int b = salakirjoitettu[4 * (i * kuvanLeveys + j) + 2];
int a = salakirjoitettu[4 * (i * kuvanLeveys + j) + 3];
salakirjoitettuColor[i, j] = new Color(r, g, b, a);
}
}
image.SetData(salakirjoitettuColor);
}
}
}Salakirjoitettavat merkit pitää pätkiä siis kahden bitin jonoihin. Muuta ensin merkki int-luvuksi. Sen jälkeen tämän merkin kaksi vähiten merkitsevää bittiä saat käyttämällä bittimaskia 0x3: int bits01 = myNumber & 0x3;
Tässä 0x3 on siis luku 00000011 heksadesimaalilukuna ja &-operaattorin ansiosta bits01-muuttujaan tallennetaan tasan ne luvut jotka sattuvat myNumberissa olemaan kahdessa ekassa bitissä.
Kun nämä bitit on nyt "käytetty", niin voit rullata bittejä oikealle päin sanomalla myNumber = myNumber >> 2;. Sitten seuraavat bitit voit ottaa käyttämällä yllä esiteltyä tapaa (laita muuttujalle nimeksi vaikka bits23.
Sitten kirjoittaessasi tätä salakirjoitettua dataa alkuperäisen kuvan päälle käytä & (bitwise and) ja | (bitwise or) operaattoreita sopivasti.
These are the current permissions for this document; please modify if needed. You can always modify these permissions from the manage page.