Reputation: 63
I've been trying to write a simple Port Scanner using a simple switch function built with if. I've already searched here for a proper solution on how to make the switch function as usable as in C++ or similliar. I found the problem already being discussed on here Replacements for switch statement in Python? and i've tried a few of these approaches but haven't had any luck so far making it run properly. Whatever method i picked from the link i always get a syntax error on the second switch case like this :
File "/home/h4v0kkx0008c/Desktop/Sources/setup/PortScannerV1.py", line 44
if case(2):
^
SyntaxError: invalid syntax
What might be the problem here?
This is the full code i wrote so far :
from socket import *
import time, socket, os, sys, string, argparse, logging, math
n = raw_input("Choose Port range: \n(1)Standard Ports: 0 - 1025\n(2)Middle Range: 1025 - 5000\n(3)Higher Range: 5000 - 49151\n(4)Highest Range: 49151 - 65535\n(5)All Ports: 0 - 65535\n(6)Custom ")
class switch(object):
value = None
def __new__(class_, value):
class_.value = value
return True
def case(*args):
return any((arg == switch.value for arg in args))
while switch(n):
if case(1):
print"Your choice is: Standard Ports"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
for i in range(0, 1025):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
if case(2):
print"Your choice is: Middle Range"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
for i in range(1025, 5000):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
break
if case(3):
print"Your choice is: Higher Range"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
for i in range(500, 49151):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
break
if case(4):
print"Your choice is: Highest Range"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
for i in range(49151, 65535):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
break
if case(5):
print"Your choice is: All Ports"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
for i in range(0, 65535):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
break
if case(6):
print"Your choice is: Custom"
target= raw_input("Please specify Host or Ip to scan: ")
targetIP = gethostbyname(target)
print 'Starting scan on host ', targetIP
startPort= raw_input("Specify starting Port:")
endPort= raw_input("Specify end Port:")
for i in range(startPort, endPort):
s = socket(AF_INET, SOCK_STREAM)
result = s.connect_ex((targetIP, i)
break
Upvotes: 2
Views: 7691
Reputation: 823
In Python 3.10 there will be a new syntax called "Structural Pattern Matching" or match/case
. This is how it looks in its generic form:
match subject:
case <pattern_1>:
<action_1>
case <pattern_2>:
<action_2>
case <pattern_3>:
<action_3>
case _:
<action_wildcard>
Here is a simple example:
def http_error(status):
match status:
case 400:
return "Bad request"
case 404:
return "Not found"
case 418:
return "I'm a teapot"
case _:
return "Something's wrong with the Internet"
Links:
Upvotes: 1
Reputation: 8192
If you need to share a set of local variables between the blocks of code in a case-equivalent statement, then a dict of functions may not be the right answer. At the very least you'll have to pass a context entity to all of the functions. Or turn them into class methods with an __init__()
to initialize them and store the context in self.whatever
The simpler way is just to use
if switchvar == value1:
...
elif switchvar==value2:
...
elif # as many more as you need
else: #default
...
This differs from a case statement only in that you can't flow off the end of one block into the next (whereas with functions, you can call then from within other ones). Note that in languages with a case statement, flowing off the end of one block in a case statement into the next is frowned on if not heavily commented. It's commonly a bug, though occasionally useful.
Note the Pythonic if variable in [value1, value2, value3, ...]:
is the equivalent of a multiplicity of case labels for value1, value2, ... at the top of the same block.
Upvotes: 1
Reputation: 16733
The way you are trying to solve this problem does not seems pythonic. Since switch statements don't exist in python, you can simulate switch like behaviour using dictionaries, since functions and classes are first class objects in python.
def func1():
# do some operation
def func2():
# some other operation
def default_func():
# some default action
options = {
'1': func1,
'2': func2,
'default': default_func
}
value = raw_input('enter a number')
result = options.get(int(value), options.get('default'))()
If your functions are simple enough, you can definitely use lambdas for values, which would be definitely be more concise.
Upvotes: 4