Digitale watermerken
Deze pagina is buiten gebruik genomen
Hier is mogelijk ook een meer gedetailleerde reden voor verwijderingsnominatie te vinden. Het is mogelijk dat de tekst met toestemming van de auteur of van een andere bron gekopieerd is, maar dat dit niet duidelijk gemaakt is bij het aanmaken van dit artikel. Indien dit het geval is, kaart dit dan a.u.b. aan op de overlegpagina van dit artikel en op de betreffende verwijderlijst. Als je een auteursrechtvrije invulling voor deze pagina weet, aarzel dan vooral niet en vervang deze tekst door jouw bijdrage. Vergeet deze pagina dan niet van de verwijderlijst te halen! Als het artikel dusdanig is verbeterd en aangepast dat het wel binnen Wikipedia past, kan dit sjabloon verwijderd worden. Geef dit aan op de lijst door het toevoegen van de reden. (↓) |
Digitaal watermerken is een techniek om extra informatie te verstoppen in digitale informatie zoals bijvoorbeeld in digitale afbeeldingen, digitale audio/video en dergelijke.
Deze techniek wordt gebruikt voor onder andere de auteursrechten te beschermen zodat illegale kopies opgespoord kunnen worden. Digitale watermerken worden ook gebruikt om geheime boodschappen door te geven of kan dienen als integriteitsbewijs.
[bewerk] Verschillende watermerken
Digitale watermerken kunnen kunnen in twee categoriën verdeeld worden:
- Onzichtbaar watermerk (steganografie)
Het watermerk is zodanig geplaatst dat het de orginele data zo weinig veranderd dat het haast niet op te merken valt. Er zijn vele technieken om dit te doen maar meestal wordt dit gedaan door de minst significante bit(s) van een byte te te gebruiken voor het watermerk.
- Zichtbaar watermerk
Het watermerk wordt zodanig geplaatst dat het duidelijk zichtbaar is. Zichtbare watermerken worden gebruikt voor onder andere logo’s te plaatsen in afbeeldingen.
[bewerk] Hoe het werkt
Een voorbeeld in C# (programmeertaal). Hieronder een deel code in C# geschreven om een watermerk te plaatsen in een afbeelding.
Psuedocode voor data te verstoppen :
Voor alle bytes in de berichtenstroom |
---|
Lees een byte van de sleutelstroom, sla het op in currentkey |
Lees een byte van de berichtenstroom |
XOR deze bytes, sla op in currentbyte |
mov e key pixels naar rechts, verplaats naar onderen indien nodig |
verkrijg de kleur van de pixel |
verplaats de R,G of B-waarde naar currentbyte |
Psuedocode voor het watermerk er terug uit te halen :
Voor alle verwachte bytes van de boodschap |
---|
Lees een byte van een sleutelstroom |
Bereken de positie van de volgende pixel |
verkrijg de kleur van de volgende pixel |
verplaats de R,G of B-waarde naar de berichtenstroom |
Het proces begint met de lengte van het watermerk als geheime boodschap in tekstvorm in de eerste pixel van de afbeelding te stoppen. Deze lengte is later nodig om de boodschap er terug uit te kunnen halen.
messageLength = (Int32)messageStream.Length; //hier wat lengte conflicten behandelen //... String colorValue = messageLength.ToString("x"); colorValue = UnTrimColorString(colorValue, 6); int red = Int16.Parse(colorValue.Substring(0,2), NumberStyles.HexNumber); int green = Int16.Parse(colorValue.Substring(2,2), NumberStyles.HexNumber); int blue = Int16.Parse(colorValue.Substring(4,2), NumberStyles.HexNumber); pixelColor = Color.FromArgb(red, green, blue); bitmap.SetPixel(0,0, pixelColor);
Dan leest het een byte van het sleutelwoord (keystream) om de volgende positie te berekenen van de volgende pixel die gebruikt zal worden om het watermerk erin te plaatsen.
//start met de tweede pixel Point pixelPosition = new Point(1,0); //Loop over the message for(int messageIndex=0; messageIndex<messageLength; messageIndex++){ //repeat the key, if it is shorter than the message if(keyStream.Position == keyStream.Length){ keyStream.Seek(0, SeekOrigin.Begin); } //Get the next pixel-count from the key, use "1" if it's 0 currentKeyByte = (byte)keyStream.ReadByte(); currentStepWidth = (currentKeyByte==0) ? (byte)1 : currentKeyByte; //jump to reverse-read position and read from the end of the stream keyPosition = keyStream.Position; keyStream.Seek(keyPosition, SeekOrigin.End); currentReverseKeyByte = (byte)keyStream.ReadByte(); //jump back to normal read position keyStream.Seek(keyPosition, SeekOrigin.Begin); //Perform line breaks, if current step is wider than the image while(currentStepWidth > bitmapWidth){ currentStepWidth -= bitmapWidth; pixelPosition.Y++; } //Move X-position if((bitmapWidth - pixelPosition.X) < currentStepWidth){ pixelPosition.X = currentStepWidth - (bitmapWidth - pixelPosition.X); pixelPosition.Y++; }else{ pixelPosition.X += currentStepWidth; }
De volgende stap is de pixel nemen en de boodschap-byte in een kleuren component stoppen of in alle componenten als het programma in grayscale modus is :
//Get color of the "clean" pixel pixelColor = bitmap.GetPixel(pixelPosition.X, pixelPosition.Y); //To add a bit of confusion, xor the byte with //a byte read from the keyStream int currentByte = messageStream.ReadByte() ^ currentReverseKeyByte; if(useGrayscale){ pixelColor = Color.FromArgb(currentByte, currentByte, currentByte); }else{ //Change one component of the color to the message-byte SetColorComponent(ref pixelColor, currentColorComponent, currentByte); //Rotate color components currentColorComponent = (currentColorComponent==2) ? 0 : (currentColorComponent+1); } } //end of for - proceed to next byte
Als de method in extractie mode is leest het de lengte van de boodschap en de componenten in plaats van deze te plaatsen zoals hierboven beschreven. Hier ziet u hoe de lengte verkregen wordt door de eerste pixel in te lezen :
pixelColor = bitmap.GetPixel(0,0); //UnTrimColorString fill the String with '0'-chars //to match the specified length String colorString = UnTrimColorString(pixelColor.R.ToString("x"), 2) + UnTrimColorString(pixelColor.G.ToString("x"), 2) + UnTrimColorString(pixelColor.B.ToString("x"), 2); messageLength = Int32.Parse(colorString, NumberStyles.HexNumber); messageStream = new MemoryStream(messageLength);
De pixel coördinaten worden op dezelfde manier berekend als hierboven vermeld, daarna wordt de verborgen byte van de boodschap uit de color values gehaald :
//Get color of the modified pixel pixelColor = bitmap.GetPixel(pixelPosition.X, pixelPosition.Y); //Extract the hidden message-byte from the color byte foundByte = (byte)(currentReverseKeyByte ^ GetColorComponent(pixelColor, currentColorComponent)); messageStream.WriteByte(foundByte); //Rotate color components currentColorComponent = (currentColorComponent==2) ? 0 : (currentColorComponent+1); } //end of for - proceed to next byte