This repository has been archived by the owner on Mar 10, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreveal.go
68 lines (55 loc) · 1.63 KB
/
reveal.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package main
import (
"errors"
"image"
"strconv"
)
var (
messageNotFound = errors.New("Message Not Found =)")
)
// Extract message from image's pixels.
// by default utf8 encoding is used.
func revealMessage(img image.Image, conf *Configuration) (buff string, err error) {
width, height := img.Bounds().Dx(), img.Bounds().Dy()
rgbaObject := toRGBA(img)
var msgLen int = 0 // message length
var msgLenAsString string // message length as string(need to be parsed to int)
var cbuff int = 0 // buffer that host a char extracted bit by bit from pixels
var n uint8 = 0 // used to decode `cbuff`
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
cRGBA := rgbaObject.RGBAAt(x, y) // getting rgba color from `x` and `y` position
for _, c := range []uint8{cRGBA.R, cRGBA.G, cRGBA.B} {
lsb := c & 1 // getting least significant bit
cbuff += int(lsb << (7 - n)) // decoding `lsb` bit using utf8 encoding as default
if n == 8 {
b := byte(cbuff) // casting integer to byte
// finding message length
if b > 47 && b < 58 && len(buff) == 0 {
msgLenAsString += string(b)
} else {
msgLen, _ = strconv.Atoi(msgLenAsString) // parsing message length to integer
// if buffer already reached message length
// let's go to end
if len(buff) == msgLen {
goto end
}
buff += string(b)
}
// let's restart `n` and `cbuff` to start
// another char finding and decoding.
n, cbuff = 0, 0
}
n++
}
}
}
end:
if msgLen > 0 {
buff = conf.Encryption.Decrypt(buff)
} else {
buff = ""
err = messageNotFound
}
return
}