I have a really annoying problem that I tried to solve for a few days. I can't find any information on the net.
I tried to solve it myself, consulted with the documentations. But nothing works.
My problem is
When I assign a variable X
with RandMAC()
function, X
should be the same every time I use it.
Like, X = RandMAC()
, and let say X
is now AA:BB:CC:DD:EE:FF
and when I print X for 3 times, it should be something like this.
X = AA:BB:CC:DD:EE:FF
X = AA:BB:CC:DD:EE:FF
X = AA:BB:CC:DD:EE:FF
But what the code actually does is
X = AA:BB:CC:DD:EE:FF
X = 00:0A:0B:0C:0D:0E:0F
X = 11:22:33:44:55:66
So it changed every time I call print X.
How can I solve this issue ?
My code is as follow.
from scapy.all import *
X = RandMAC()
print X
print X
print X
Thank you all in advance.
RandMAC
is a class, and when you call RandMAC()
what you get is an instance of that class. scapy
has a whole lot of these RandXXXXX
classes, and they all behave in the same way: an instance of the class is really a sort of random-thing-generator, not a fixed (but randomly chosen) thing. In this instance, a RandMac
is built out of six RandByte
s, and a RandByte
turns into a random value from 0 to 255 every time its value is asked for.
The idea, I think, is to make it easy to build (e.g.) an IP packet randomizer that gives you IP packets that are all the same except that a couple of fields are chosen at random for every packet.
So, anyway, many operations on random-thing objects are effectively delegated to the results of "fixing" them (i.e., picking a particular random value); see volatile.py
in the source code, class VolatileValue
; the magic happens in the __getattr__
method. In particular, this applies to stringifying via __str__
, which is what str()
does as observed by Lycha and what print
does as observed by Karun S.
If you want to get a single random value, the nearest thing to the Right Way is probably to call the _fix
method: X = RandMAC()._fix()
. That happens to be the same as str
for RandMAC
, but e.g. if you have a random integer then _fix
will give you an actual integer while str
will give you its string representation.
None of this appears to be documented. Don't make any large bets on it still working in future versions. (But, for what it's worth, volatile.py
hasn't changed for about two years.)