|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "bufio" |
| 5 | + "bytes" |
| 6 | + "flag" |
| 7 | + "fmt" |
| 8 | + "image" |
| 9 | + "io/ioutil" |
| 10 | + "log" |
| 11 | + "os" |
| 12 | + |
| 13 | + "github.com/pastelnetwork/steganography" |
| 14 | +) |
| 15 | + |
| 16 | +var pictureInputFile string |
| 17 | +var pictureOutputFile string |
| 18 | +var messageInputFile string |
| 19 | +var messageOutputFile string |
| 20 | +var decode bool |
| 21 | +var encode bool |
| 22 | +var help bool |
| 23 | + |
| 24 | +// init creates the necessary flags to run program from the command line |
| 25 | +func init() { |
| 26 | + |
| 27 | + flag.BoolVar(&decode, "d", false, "Specifies if you would like to decode a message from a given PNG file") |
| 28 | + flag.BoolVar(&encode, "e", false, "Specifies if you would like to encode a message to a given PNG file") |
| 29 | + |
| 30 | + flag.StringVar(&pictureInputFile, "i", "", "Path to the the input image") |
| 31 | + flag.StringVar(&pictureOutputFile, "o", "encoded.png", "Path to the the output image") |
| 32 | + |
| 33 | + flag.StringVar(&messageInputFile, "mi", "", "Path to the message input file") |
| 34 | + flag.StringVar(&messageOutputFile, "mo", "", "Path to the message output file") |
| 35 | + |
| 36 | + flag.BoolVar(&help, "help", false, "Help") |
| 37 | + |
| 38 | + flag.Parse() |
| 39 | +} |
| 40 | + |
| 41 | +// OpenImageFromPath returns a image.Image from a file path. A helper function to deal with decoding the image into a usable format. This method is optional. |
| 42 | +func OpenImageFromPath(filename string) (image.Image, error) { |
| 43 | + inFile, err := os.Open(filename) |
| 44 | + if err != nil { |
| 45 | + return nil, err |
| 46 | + } |
| 47 | + defer inFile.Close() |
| 48 | + reader := bufio.NewReader(inFile) |
| 49 | + img, _, err := image.Decode(reader) |
| 50 | + if err != nil { |
| 51 | + return nil, err |
| 52 | + } |
| 53 | + return img, nil |
| 54 | +} |
| 55 | + |
| 56 | +func main() { |
| 57 | + if encode { |
| 58 | + message, err := ioutil.ReadFile(messageInputFile) // Read the message from the message file (alternative to os.Open ) |
| 59 | + if err != nil { |
| 60 | + print("Error reading from file!!!") |
| 61 | + return |
| 62 | + } |
| 63 | + |
| 64 | + inFile, err := os.Open(pictureInputFile) // Opens input file provided in the flags |
| 65 | + if err != nil { |
| 66 | + log.Fatalf("Error opening file %s: %v", pictureInputFile, err) |
| 67 | + } |
| 68 | + defer inFile.Close() |
| 69 | + |
| 70 | + reader := bufio.NewReader(inFile) // Reads binary data from picture file |
| 71 | + img, _, err := image.Decode(reader) |
| 72 | + if err != nil { |
| 73 | + log.Fatalf("Error opening file %v", err) |
| 74 | + } |
| 75 | + encodedImg := new(bytes.Buffer) |
| 76 | + err = steganography.Encode(encodedImg, img, message) // Calls library and Encodes the message into a new buffer |
| 77 | + if err != nil { |
| 78 | + log.Fatalf("Error encoding message into file %v", err) |
| 79 | + } |
| 80 | + outFile, err := os.Create(pictureOutputFile) // Creates file to write the message into |
| 81 | + if err != nil { |
| 82 | + log.Fatalf("Error creating file %s: %v", pictureOutputFile, err) |
| 83 | + } |
| 84 | + bufio.NewWriter(outFile).Write(encodedImg.Bytes()) // writes file to disk |
| 85 | + |
| 86 | + } else if decode { |
| 87 | + |
| 88 | + inFile, err := os.Open(pictureInputFile) // Opens input file provided in the flags |
| 89 | + if err != nil { |
| 90 | + log.Fatalf("Error opening file %s: %v", pictureInputFile, err) |
| 91 | + } |
| 92 | + defer inFile.Close() |
| 93 | + |
| 94 | + reader := bufio.NewReader(inFile) |
| 95 | + img, _, err := image.Decode(reader) |
| 96 | + if err != nil { |
| 97 | + log.Fatal("error decoding file", img) |
| 98 | + } |
| 99 | + |
| 100 | + sizeOfMessage := steganography.GetMessageSizeFromImage(img) // Uses the library to check the message size |
| 101 | + |
| 102 | + msg := steganography.Decode(sizeOfMessage, img) // Read the message from the picture file |
| 103 | + |
| 104 | + // if the user specifies a location to write the message to... |
| 105 | + if messageOutputFile != "" { |
| 106 | + err := ioutil.WriteFile(messageOutputFile, msg, 0644) // write the message to the given output file |
| 107 | + |
| 108 | + if err != nil { |
| 109 | + fmt.Println("There was an error writing to file: ", messageOutputFile) |
| 110 | + } |
| 111 | + } else { // otherwise, print the message to STDOUT |
| 112 | + for i := range msg { |
| 113 | + fmt.Printf("%c", msg[i]) |
| 114 | + } |
| 115 | + } |
| 116 | + } else { |
| 117 | + fmt.Println("How to use this script:") |
| 118 | + fmt.Println("-i: the input image to encode in / decode from") |
| 119 | + fmt.Println() |
| 120 | + fmt.Println("-e: take a message and encodes it into a specified location") |
| 121 | + fmt.Println("-mi: input message to for the encoding option (ENCODING ONLY)") |
| 122 | + fmt.Println("-o: where you would like to store the encodeded image (ENCODING ONLY)") |
| 123 | + fmt.Println("\t+ EX: ./main -e -i plain.png -mi message.txt -o secret.png") |
| 124 | + fmt.Println() |
| 125 | + fmt.Println("-d: take a picture and decodes the message from it") |
| 126 | + fmt.Println("-mo: output message. Lempty for STDIO (DECODING ONLY)") |
| 127 | + fmt.Println("\t+ EX: ./stego -d -i secret.png -mo secret.txt") |
| 128 | + return |
| 129 | + } |
| 130 | +} |
0 commit comments