Source code for pysteg.jsteg.f1
## $Id: f1.py 1494 2009-04-30 13:10:41Z css1hs $
## -*- coding: utf-8 -*-
"""
The JSTEG stego-system.
"""
print "[f1] $Id$"
# #####################
# The Jsteg Stegosystem
# #####################
#
# :Module: pysteg.jsteg.f1
# :Date: $Date: 2010-07-16 10:43:38 +0100 (Fri, 16 Jul 2010) $
# :Revision: $Revision: 1559 $
# :Copyright: © 2009: University of Surrey, UK
# :Author: Hans Georg Schaathun <georg@schaathun.net> (2009)
from random import SystemRandom
from exceptions import *
from stegbase import stegbase
sysrnd = SystemRandom()
# Decode a single sample using Jsteg (mod 2)
[docs]def jstegInterpret(y):
"""Decode a coefficient x Jsteg style. Returns None when x=0,1."""
x = int(y) # Why on Earth do we occasionally get float input?
if x == 0: return None
elif x == 1: return None
else: return x%2
[docs]class f1(stegbase):
"""The F1 object handles a list of JPEG AC coefficients and
embeds and extracts messages using Jsteg."""
# Calculate embedding capacity
[docs] def embedAnalysis(self):
"""Estimate the embedding capacity."""
A = map ( lambda(x): (int(x)>>1) > 0, self )
self.capacity = A.count(True)
[docs] def interpret(self,y): return jstegInterpret(y)
# Update coefficients
# This should be the only method modifying coefficients
[docs] def flipnext(self):
"""Flip the message bit in the next position.
(Does not proceed to the subsequent bit.)"""
self[self.next] ^= 1
# self.checknext() -- Not necessary with Jsteg
self.changed += 1
# Stepping methods - used to traverse the sequence
[docs] def checknext( self ):
"""Check that the next coefficient can be used for Jsteg.
Move pointer if necessary."""
if not self.morebits: return False
while (int(self[self.next])>>1) == 0:
if not self._auxstep(): return False
return self.morebits