|
フルカラーの画像データに任意のファイルを埋め込みます。
RGB各8Bitから各下位3,3,2bit(=1byte)を利用します。
つまり、1dotにつき1byteずつ書き込んでいきます。
埋め込み可能なファイル上限は画像サイズ(横dot × 縦dot)になります。
また、埋め込みファイルの判定に判別文字列+復元用にファイル名の長さ(1byte)+
ファイル名+ファイルサイズ(4byte)をヘッダーとして使用しています。
※このプログラムでは、復元されたファイルの一部が欠損・欠落するようです。
!' ステガノグラフィー
OPTION CHARACTER BYTE
DECLARE EXTERNAL FUNCTION GETDATA
PUBLIC NUMERIC XSIZE,YSIZE,ADR
FILE GETNAME F$,"BMP,JPG,GIF,PNGファイル|*.BMP;*.JPG;*.GIF;*.PNG"
IF F$="" THEN STOP
CALL PICTURELOAD(F$,XSIZE,YSIZE)
LET KEY$="Steganography" !'判別文字列
LET ADR=0
LET D$=""
FOR I=1 TO LEN(KEY$)
LET D$=D$&CHR$(GETDATA)
NEXT I
IF D$<>KEY$ THEN
PRINT "任意ファイルを画像に埋め込みます"
PRINT XSIZE*YSIZE-(LEN(KEY$)+5+255);"Byteまで"
FILE GETNAME F$,"埋め込みファイル|*.*"
IF F$="" THEN STOP
FILE SPLITNAME (F$) PATH$, NAME$, EXT$
LET NAME$=NAME$&EXT$
PRINT "埋め込みファイル:";NAME$
OPEN #1:NAME F$
ASK #1 : FILESIZE FSIZE
PRINT "ファイルサイズ:";FSIZE;"Byte"
IF XSIZE*YSIZE-(LEN(KEY$)+LEN(NAME$)+5)<FSIZE THEN
PRINT "ファイルが大き過ぎます。"
CLOSE #1
STOP
END IF
LET ADR=0
FOR I=1 TO LEN(KEY$)
CALL PUTDATA(ORD(KEY$(I:I)))
NEXT I
LET NAMESIZE=LEN(NAME$)
CALL PUTDATA(NAMESIZE)
FOR I=1 TO NAMESIZE
CALL PUTDATA(ORD(NAME$(I:I)))
NEXT I
LET FSIZE$=MKL$(FSIZE)
FOR I=1 TO 4
CALL PUTDATA(ORD(FSIZE$(I:I)))
NEXT I
FOR I=1 TO FSIZE
CHARACTER INPUT #1 : A$
CALL PUTDATA(ORD(A$))
NEXT I
CLOSE #1
FILE GETSAVENAME F$,"保存BMP,PNGファイル|*.BMP;*.PNG"
IF F$="" THEN STOP
IF POS(F$,".")=0 THEN LET F$=F$&".png"
GSAVE F$
ELSE
LET ADR=LEN(KEY$)
PRINT "画像からファイルを抽出します"
LET NAMESIZE=GETDATA
LET FILENAME$=""
FOR I=1 TO NAMESIZE
LET FILENAME$=FILENAME$&CHR$(GETDATA)
NEXT I
PRINT "抽出ファイル名:";FILENAME$
LET S$=""
FOR I=1 TO 4
LET S$=S$&CHR$(GETDATA)
NEXT I
LET FSIZE=CVL(S$)
PRINT "ファイルサイズ:";FSIZE
FILE GETSAVENAME F$,"抽出ファイル|*.*"
IF F$="" THEN STOP
OPEN #1:NAME F$
ERASE #1
FOR I=1 TO FSIZE
PRINT #1:CHR$(GETDATA);
NEXT I
CLOSE #1
END IF
END
EXTERNAL SUB PUTDATA(N)
LET XX=MOD(ADR,XSIZE)
LET YY=INT(ADR/XSIZE)
LET ADR=ADR+1
CALL GETPOINT(XX,YY,R,G,B)
LET R=BITAND(R,BVAL("11111000",2))
LET R=BITOR(R,BITAND(N,BVAL("11100000",2))/32)
LET G=BITAND(G,BVAL("11111000",2))
LET G=BITOR(G,BITAND(N,BVAL("00011100",2))/4)
LET B=BITAND(B,BVAL("11111100",2))
LET B=BITOR(B,BITAND(N,BVAL("00000011",2)))
CALL PSET(XX,YY,R,G,B)
END SUB
EXTERNAL FUNCTION GETDATA
LET XX=MOD(ADR,XSIZE)
LET YY=INT(ADR/XSIZE)
LET ADR=ADR+1
CALL GETPOINT(XX,YY,R,G,B)
LET GETDATA=BITAND(R,7)*32+BITAND(G,7)*4+BITAND(B,3)
END FUNCTION
EXTERNAL SUB RGB(X,R,G,B)
LET B=MOD(INT(X/65536),256)
LET G=MOD(INT(X/256),256)
LET R=MOD(X,256)
END SUB
EXTERNAL SUB GETPOINT(X,Y,R,G,B)
ASK PIXEL VALUE(X,Y) C
CALL RGB(C,R,G,B)
END SUB
EXTERNAL SUB PSET(X,Y,R,G,B)
SET COLOR COLORINDEX(R/255,G/255,B/255)
PLOT POINTS:X,Y
END SUB
EXTERNAL SUB PICTURELOAD(N$,XSIZE,YSIZE)
CLEAR
SET COLOR MODE "NATIVE"
SET POINT STYLE 1
GLOAD N$
LET XSIZE=PIXELX(1)
LET YSIZE=PIXELY(1)
SET BITMAP SIZE XSIZE,YSIZE
SET WINDOW 0,XSIZE-1,YSIZE-1,0
END SUB
EXTERNAL FUNCTION MKL$(A)
OPTION CHARACTER BYTE
DECLARE STRING A$,B$,C$,D$
IF A<0 THEN LET A=A+2^32
LET A$=CHR$(MOD(A,256))
LET B$=CHR$(MOD(INT(A/256),256))
LET C$=CHR$(MOD(INT(A/65536),256))
LET D$=CHR$(MOD(INT(A/16777216),256))
LET MKL$=A$&B$&C$&D$
END FUNCTION
EXTERNAL FUNCTION CVL(A$)
OPTION CHARACTER BYTE
DECLARE NUMERIC A
LET A$=LEFT$(A$,4)
LET A=ORD(A$(1:1))+ORD(A$(2:2))*256+ORD(A$(3:3))*256^2+ORD(A$(4:4))*256^3
IF A>=2^31-1 THEN LET A=A-2^32
LET CVL=A
END FUNCTION
|
|