mirror of https://gitlab.com/bashrc2/epicyon
Decoy is a more descriptive term
parent
55fc1c8d91
commit
75be6ddfee
82
media.py
82
media.py
|
@ -56,58 +56,68 @@ def _removeMetaData(imageFilename: str, outputFilename: str) -> None:
|
|||
os.system('/usr/bin/mogrify -strip ' + outputFilename) # nosec
|
||||
|
||||
|
||||
def _getCityPulse(currTimeOfDay, doppelgangerSeed: int) -> float:
|
||||
"""The data doppelganger
|
||||
def _getCityPulse(currTimeOfDay, decoySeed: int) -> (float, float):
|
||||
"""The data decoy
|
||||
This simulates expected average patterns of movement in a city.
|
||||
Jane or Joe average lives and works in the city, commuting in
|
||||
and out of the central district for work. They have a unique
|
||||
life pattern, which machine learning can latch onto.
|
||||
This returns a polar coordinate:
|
||||
Distance from the city centre is in the range 0.0 - 1.0
|
||||
Angle is in radians
|
||||
"""
|
||||
randgen = random.Random(doppelgangerSeed)
|
||||
randgen = random.Random(decoySeed)
|
||||
variance = 3
|
||||
busyStates = ("work", "shop", "play", "party")
|
||||
dataDoppelgangerState = "sleep"
|
||||
dataDoppelgangerIndex = 0
|
||||
dataDecoyState = "sleep"
|
||||
dataDecoyIndex = 0
|
||||
weekday = currTimeOfDay.weekday()
|
||||
minHour = 7 + randint(0, variance)
|
||||
maxHour = 17 + randint(0, variance)
|
||||
if currTimeOfDay.hour > minHour:
|
||||
if currTimeOfDay.hour <= maxHour:
|
||||
if weekday < 5:
|
||||
dataDoppelgangerState = "work"
|
||||
dataDoppelgangerIndex = 1
|
||||
dataDecoyState = "work"
|
||||
dataDecoyIndex = 1
|
||||
elif weekday == 5:
|
||||
dataDoppelgangerState = "shop"
|
||||
dataDoppelgangerIndex = 2
|
||||
dataDecoyState = "shop"
|
||||
dataDecoyIndex = 2
|
||||
else:
|
||||
dataDoppelgangerState = "play"
|
||||
dataDoppelgangerIndex = 3
|
||||
dataDecoyState = "play"
|
||||
dataDecoyIndex = 3
|
||||
else:
|
||||
if weekday < 5:
|
||||
dataDoppelgangerState = "evening"
|
||||
dataDoppelgangerIndex = 4
|
||||
dataDecoyState = "evening"
|
||||
dataDecoyIndex = 4
|
||||
else:
|
||||
dataDoppelgangerState = "party"
|
||||
dataDoppelgangerIndex = 5
|
||||
dataDecoyState = "party"
|
||||
dataDecoyIndex = 5
|
||||
angleRadians = \
|
||||
(randgen.randint(0, 100000 - 5 + dataDoppelgangerIndex) / 100000) * \
|
||||
(randgen.randint(0, 100000 - 5 + dataDecoyIndex) / 100000) * \
|
||||
2 * math.pi
|
||||
# what consitutes the central district is fuzzy
|
||||
centralDistrictFuzz = (randgen.randint(0, 100000) / 100000) * 0.1
|
||||
busyRadius = 0.3 + centralDistrictFuzz
|
||||
if dataDoppelgangerState in busyStates:
|
||||
# if we are busy then we're somewhere in the city center
|
||||
distanceFromCityCenter = \
|
||||
(randgen.randint(0, 100000) / 100000) * busyRadius
|
||||
# some people are quite random, others have more predictable habits
|
||||
decoyRandomness = randgen.randint(10, 20)
|
||||
# occasionally throw in a wildcard to keep the machine learning guessing
|
||||
if randint(0, 100) < decoyRandomness:
|
||||
distanceFromCityCenter = (randint(0, 100000) / 100000)
|
||||
angleRadians = (randint(0, 100000) / 100000) * 2 * math.pi
|
||||
else:
|
||||
# otherwise we're in the burbs
|
||||
distanceFromCityCenter = busyRadius + \
|
||||
((1.0 - busyRadius) * (randgen.randint(0, 100000) / 100000))
|
||||
# what consitutes the central district is fuzzy
|
||||
centralDistrictFuzz = (randgen.randint(0, 100000) / 100000) * 0.1
|
||||
busyRadius = 0.3 + centralDistrictFuzz
|
||||
if dataDecoyState in busyStates:
|
||||
# if we are busy then we're somewhere in the city center
|
||||
distanceFromCityCenter = \
|
||||
(randgen.randint(0, 100000) / 100000) * busyRadius
|
||||
else:
|
||||
# otherwise we're in the burbs
|
||||
distanceFromCityCenter = busyRadius + \
|
||||
((1.0 - busyRadius) * (randgen.randint(0, 100000) / 100000))
|
||||
return distanceFromCityCenter, angleRadians
|
||||
|
||||
|
||||
def spoofGeolocation(baseDir: str,
|
||||
city: str, currTime, doppelgangerSeed: int,
|
||||
city: str, currTime, decoySeed: int,
|
||||
citiesList: []) -> (float, float, str, str):
|
||||
"""Given a city and the current time spoofs the location
|
||||
for an image
|
||||
|
@ -156,7 +166,7 @@ def spoofGeolocation(baseDir: str,
|
|||
datetime.timedelta(hours=approxTimeZone)
|
||||
# patterns of activity change in the city over time
|
||||
(distanceFromCityCenter, angleRadians) = \
|
||||
_getCityPulse(currTimeAdjusted, doppelgangerSeed)
|
||||
_getCityPulse(currTimeAdjusted, decoySeed)
|
||||
# Get the position within the city, with some randomness added
|
||||
latitude += \
|
||||
distanceFromCityCenter * cityRadius * math.cos(angleRadians)
|
||||
|
@ -189,14 +199,14 @@ def _spoofMetaData(baseDir: str, nickname: str, domain: str,
|
|||
return
|
||||
|
||||
# get the random seed used to generate a unique pattern for this account
|
||||
doppelgangerSeedFilename = \
|
||||
baseDir + '/accounts/' + nickname + '@' + domain + '/doppelgangerseed'
|
||||
doppelgangerSeed = 63725
|
||||
if os.path.isfile(doppelgangerSeedFilename):
|
||||
with open(doppelgangerSeedFilename, 'r') as fp:
|
||||
doppelgangerSeed = int(fp.read())
|
||||
decoySeedFilename = \
|
||||
baseDir + '/accounts/' + nickname + '@' + domain + '/decoyseed'
|
||||
decoySeed = 63725
|
||||
if os.path.isfile(decoySeedFilename):
|
||||
with open(decoySeedFilename, 'r') as fp:
|
||||
decoySeed = int(fp.read())
|
||||
else:
|
||||
doppelgangerSeed = randint(10000, 10000000000000)
|
||||
decoySeed = randint(10000, 10000000000000)
|
||||
|
||||
if os.path.isfile('/usr/bin/exiftool'):
|
||||
print('Spoofing metadata in ' + outputFilename + ' using exiftool')
|
||||
|
@ -206,7 +216,7 @@ def _spoofMetaData(baseDir: str, nickname: str, domain: str,
|
|||
published = currTimeAdjusted.strftime("%Y:%m:%d %H:%M:%S+00:00")
|
||||
(latitude, longitude, latitudeRef, longitudeRef) = \
|
||||
spoofGeolocation(baseDir, spoofCity, currTimeAdjusted,
|
||||
doppelgangerSeed, None)
|
||||
decoySeed, None)
|
||||
os.system('exiftool -artist="' + nickname + '" ' +
|
||||
'-DateTimeOriginal="' + published + '" ' +
|
||||
'-FileModifyDate="' + published + '" ' +
|
||||
|
|
6
tests.py
6
tests.py
|
@ -3676,10 +3676,10 @@ def testSpoofGeolocation() -> None:
|
|||
'HOUSTON, USA:29.9803:W95.3397'
|
||||
]
|
||||
currTime = datetime.datetime.utcnow()
|
||||
doppelgangerSeed = 7634682
|
||||
decoySeed = 7634682
|
||||
cityRadius = 0.1
|
||||
coords = spoofGeolocation('', 'los angeles', currTime,
|
||||
doppelgangerSeed, citiesList)
|
||||
decoySeed, citiesList)
|
||||
assert coords[0] >= 33.9425 - cityRadius
|
||||
assert coords[0] <= 33.9425 + cityRadius
|
||||
assert coords[1] >= 118.408 - cityRadius
|
||||
|
@ -3687,7 +3687,7 @@ def testSpoofGeolocation() -> None:
|
|||
assert coords[2] == 'N'
|
||||
assert coords[3] == 'W'
|
||||
coords = spoofGeolocation('', 'unknown', currTime,
|
||||
doppelgangerSeed, citiesList)
|
||||
decoySeed, citiesList)
|
||||
assert coords[0] >= 51.8744 - cityRadius
|
||||
assert coords[0] <= 51.8744 + cityRadius
|
||||
assert coords[1] >= 0.368333 - cityRadius
|
||||
|
|
Loading…
Reference in New Issue