I'm beginner to Python ... I'd like to format the characters in Python using basic concepts and operations of Tuples and Lists as below ...
I enter 10 digit number and except last 4 digits remaining all the numbers should be replaced by 'X'. For e.g.
number = 1234567890
Expecting output as -
number = XXXXXX7890
How to mask entered characters / numbers in Python using Tuples/Lists concept not using by importing any modules or existing high functions. Is it possible ?
For e.g. entered some characters , those should be masked using * (asterisk) or # (hashed) while entering. For e.g.
password : pa55w0rd
Expecting output while entering password as -
password : ********
OR
password: ########
It is always better to use built-in modules for things sensitive like password. One way of doing is following:
import getpass
number = 1234567890
first = 'X' * max(0,len(str(number)[:-4]))
last = str(number)[-4:]
n = first + last
print(n)
# part 2
p = getpass.getpass(prompt='Enter the number : ')
if int(p) == 123:
print('Welcome..!!!')
else:
print('Please enter correct number..!!!')
If you don't want to display typed password just print:
print('######')
It does not have to be of the same length you just have to print something.
Break down what's needed: you need to convert to a string, to figure out how many characters to replace, generate a replacement string of that length, then include the tail of the original string. Also you need to be robust against, eg, strings too short to have any characters replaced.
'X' * max(0, len(str(number)) - 4) + str(number)[-4:]
For the second part: use a library.
Doing this directly is more complicated than it might seem to a beginner, because you're having to communicate with the systems which take text entry. It's going to depend upon the operating system, Windows vs "roughly everything else". For text entry outside of a web-browser or a GUI, most systems are emulating ancient text-only terminal devices because there's not yet enough reason to change that. Those devices have modes of text input (character at a time, line at a time, raw, etc) and changing them to not immediately "echo" the character typed involves some intricate system calls, and then other programming to echo a different character instead.
Thus you're going to want to use a library to take care of all those intricate details for you. Something around password entry. Given the security implications, using tested and hardened code instead of rolling your own is something I strongly encourage. Be aware that there are all sorts of issues around password handling too (constant time comparisons, memory handling, etc) such that as much as possible, you should avoid doing it at all, or move it to another program, and when you do handle it, use the existing libraries.
If you can, stick to the Python standard library and use getpass which won't echo anything for passwords, instead of printing stars.
If you really want the stars, then search https://pypi.org/ for getpass and see all the variants people have produced. Most of the ones I saw in a quick look didn't inspire confidence; pysectools seemed better than the others, but I've not used it.
Related
I recently tried to find polynomials with given points and stumbled upon the problem that I can’t use strings like normal mathematical operations: "3 + 1" + "2 + 1" because it will return "3 + 12 + 1". I than tried to just iterate over the string but had the next difficulty that I cant just unstringify operations like "+" or "-".
Does anyone know how to do solve the problem?
eval() is very dangerous
It can execute any commands, including unsafe or malicious strings.
Use Pyparsing (more info here and another question and example here).
Another option is the ast module (good example here). If you want more functionality, ast can open up more commands, but pyparsing should work well.
A third, more lightweight option is this single file parser
If this calculation will exist purely within the code, with the user having no direct access, then you can use eval().
Example:
print(eval("3 + 4"))
Output:
7
The point of eval() is to execute Python code that is stored as a string. If the user is inputting values to be used within an eval() statement, you should absolutely do some error-checking to make sure the user is inputting numbers. If your program was intended to be released for commercial use, say, you run the risk of a user inputting Python code that can be executed using eval().
I'm working through Python Programming: An Introduction to Computer Science (2nd edition). At the end of the second chapter, one of the exercises is to design a calculator. Prior to this, he has been using eval() to do calculations. I know that using eval is bad for security, but I dont know how to get around using it. I could always use it now and worry about it later, but I want to build good habits.
I want the user to enter their desired calculation as one line, like this:
>>> input('Input your expression: ')
Input your expression: 4 * 5 / 2
I've already looked at this post Pros and Cons on designing a calculator with eval . The answer gave him a link that showed how you could get around it. The way he did it seemed quite convoluted, and I don't understand how he did it.
I think I need eval() for this. My code for the calculator is below. Thank you for the help!
# Calculator.py
# This program will allow the user to input a mathematical expression (using python syntax)
# it will then evaluate the expression and print the result. It will unfortunately use eval
# but I dont know how to get around this problem. The program will loop to allow for
# multiple calculations.
expression = 'blank'
print('Calculator')
print(' ')
print('Welcome! Please input your desired expression, using python syntax.')
print('When you are finished, input end, and the program will finish.')
# Until the user inputs end, the calculator will continue to repeat.
while expression != 'end':
print('')
expression= input('Input your expression: ')
# Checks if the last digit of expression is a digit. I think this is fairly foolproof.
# I used last digit instead of first, bc a negative sign could have been in the first digit.
if expression[len(expression)-1].isdigit():
print('= ', eval(expression))
# A way to distinguish between 'end' and other strings. After this prints and loops back,
# program should end.
elif expression == 'end':
print('Shutting down... ')
# If the user inputs something where the last digit is not a digit, and is
# not end, the program will notify them and repeat.
else:
print('Enter with only digits and operators!')
eval is probably what you want here. eval is mainly discouraged because it allows any users of your app to execute arbitrary code, which obviously leads to security vulnerabilities. However, since you're doing this for learning experience, not in a publicly released app, this isn't really a concern for you. Especially if you are just learning, I'd ignore this for now (definitely don't do this in a production app).
You'll want to do: eval(input('please enter a expression')), which allows you to execute an arbitrary expression.
In the article you link, they explain that eval takes two more optional parameters, that allow you to restrict what expressions can be executed by the eval.
He sets the second parameter to {"__builtins__":None} to restrict you from using any global functions (if it is set to {}, builtin functions like abs are still available).
He sets the third parameter to a dictionary of all functions he'd like to allow the user to execute, since he just restricted the user to not being able to run any global functions previously.
Ive heard that using "input" was unsafe for password use because it interprets the input as code, and thus someone could bypass the security.
How would you go around doing that? For example, how would you do it to something like this?
password = 1234
pass_true = input("What is the password?")
if password == pass_true:
print("Access granted.")
else:
print ("Access denied.")
It's simple: To get past your check, just type password at the prompt :-) Try it!
What is the password?password
Access granted.
Explanation: input reads what you type, evaluates it as python code, and assigns the result to pass_true. So in the above, I just told it to assign the value of the variable password (which holds the real password) to pass_true.
But this code is broken even for regular use: If you type anything that doesn't look like a valid python expression, it'll trigger an error. Your example uses numbers as "passwords", but you couldn't use the same approach for arbitrary-text passwords: It wouldn't work at all, even with the correct password.
Another kind of problem is typing something damaging like os.remove(".profile") (or something worse and more elaborate) at the prompt. It won't log them in but you can see the damage it can do. Evaluating user input is just wrong, unless you're writing an interactive python interpreter.
Python 2 has raw_input() which just reads input. (In python 3, raw_input() has been renamed to input() and the old input() is gone).
So I was just reading this and if you're using Python 3.x, you'll be fine.
Otherwise, if you use input(), then you could just type password and be done.
Again, if you're using Python 3.x, don't worry.
The idea is not to keep passwords at all. You have to create hash out of input and check whether it's equal to your password's hash. But if you're just a beginner it's okay to do what you do.
The side-channel attack sboutzen mentioned is a real threat, and can be exploited using time(), from linux command-line
This article explains it in more detail
https://blog.sqreen.com/developer-security-best-practices-protecting-against-timing-attacks/
The hash could be compromised by identifying the hash used byte by byte. You would have the hash of the real password instead of the password itself, but that is why dictionary attacks are useful.
Another problem you will have with that approach is that when you compare two strings like that, you leak information and set yourself up for a side-channel attack.
The string comparison will compare the two strings one byte at a time, and if one of the bytes don't match, it returns. However, this means that an attacker knows exactly which part, of the password he is testing, is correct, and which part is not. Therefore he can reduce the entropy of a given password to 2 to the power of the length of the set of characters allowed.
When comparing passwords you should compare the two strings bytewise like so:
result = 0;
for (int i = 0; i < storedUserPass.length; i++) {
result |= storedUserPass[i] ^ incomingPasswordBytes[i];
}
When it is done, if result is equal to 0, all the bytes match, if not, they dont. This is a constant time calculation, which doesn't leak any information
This question already has answers here:
How do I print colored text to the terminal?
(64 answers)
Closed 8 years ago.
so i made a small password strength tester for me, my friends and my family, as seen here:
import re
strength = ['You didnt type anything','Terrible','weak sause','avarage','Good!','Very Strong', 'THE FORCE IS STRONG WITH THIS ONE']
score = 1
password=(raw_input("please type in the password you would like rated:"))
if len(password) < 1:
print strength[0]
if len(password) >=1 and len(password)<=4:
print strength[1]
else:
print ""
if len(password) >=7:
score+=1
print "password was made stronger by not being short"
else:
print "Your password is really short, concider making it longer"
if len (password) >=10:
score+=1
print "password was made stronger by long"
else:
print "An even longer password would make it stronger"
if re.search('[a-z]',password) and re.search('[A-Z]', password):
score+=1
print "password was made stronger by having upper & lower case letters"
else:
print "Indlucing both upper and lower case letters will make your password stronger"
if re.search('[0-9]+', password):
score+=1
print "Password was made stronger by using numbers"
else:
print "Using numbers will make your password stronger"
if re.search('[.,!,#,#,$,%,^,&,*,?,_,~,-,£,(,)]',password):
score+=1
print "Password was made stronger by using punctuation marks and characters"
else:
print "Using punctuation marks and characters will make the password stronger"
print "\n final password rating is:"
print strength[score]
what i was hoping to do is:
1st - add color to the comments i've given the user about the content of their password, good comments such as the: "password was made stronger by using numbers" will have a green output, while constructive feedback such as the "using numbers will make your password stronger" will have a red output, making it easier for the user to spot the pros and cons of his password
2nd - i was wondering, if it works the same, can i color certain items in my above "strength" list? making the first two red, the middle pair yellow and the last pair green?
ty!
IDLE's console does not support ANSI escape sequences, or any other form of escapes for coloring your output.
You can learn how to talk to IDLE's console directly instead of just treating it like normal stdout and printing to it (which is how it does things like color-coding your syntax), but that's pretty complicated. The idle documentation just tells you the basics of using IDLE itself, and its idlelib library has no documentation (well, there is a single line of documentation—"(New in 2.3) Support library for the IDLE development environment."—if you know where to find it, but that isn't very helpful). So, you need to either read the source, or do a whole lot of trial and error, to even get started.
Alternatively, you can run your script from the command line instead of from IDLE, in which case you can use whatever escape sequences your terminal handles. Most modern terminals will handle at least basic 16/8-color ANSI. Many will handle 16/16, or the expanded xterm-256 color sequences, or even full 24-bit colors. (I believe gnome-terminal is the default for Ubuntu, and in its default configuration it will handle xterm-256, but that's really a question for SuperUser or AskUbuntu.)
Learning to read the termcap entries to know which codes to enter is complicated… but if you only care about a single console—or are willing to just assume "almost everything handles basic 16/8-color ANSI, and anything that doesn't, I don't care about", you can ignore that part and just hardcode them based on, e.g., this page.
Once you know what you want to emit, it's just a matter of putting the codes in the strings before printing them.
But there are libraries that can make this all easier for you. One really nice library, which comes built in with Python, is curses. This lets you take over the terminal and do a full-screen GUI, with colors and spinning cursors and anything else you want. It is a little heavy-weight for simple uses, of course. Other libraries can be found by searching PyPI, as usual.
If your console (like your standard ubuntu console) understands ANSI color codes, you can use those.
Here an example:
print ('This is \x1b[31mred\x1b[0m.')
You can also use 'clrprint' module which works for idle, terminal and PowerShell too
pip install clrprint
from clrprint import *
clrhelp() # print's available colors and usage
user_input = clrinput("input please: ",clr='r') # just like input() [color is red]
clrprint('your text',user_input,clr='green') # just like print()
being overwhelmed by being VERY NEW to python i missed some very simple and useful commands given here: Print in terminal with colors using Python? -
eventually decided to use CLINT as an answer that was given there by great and smart people
I am trying to write a small Python 2.x API to support fetching a
job by jobNumber, where jobNumber is provided as an integer.
Sometimes the users provide ajobNumber as an integer literal
beginning with 0, e.g. 037537. (This is because they have been
coddled by R, a language that sanely considers 037537==37537.)
Python, however, considers integer literals starting with "0" to
be OCTAL, thus 037537!=37537, instead 037537==16223. This
strikes me as a blatant affront to the principle of least
surprise, and thankfully it looks like this was fixed in Python
3---see PEP 3127.
But I'm stuck with Python 2.7 at the moment. So my users do this:
>>> fetchJob(037537)
and silently get the wrong job (16223), or this:
>>> fetchJob(038537)
File "<stdin>", line 1
fetchJob(038537)
^
SyntaxError: invalid token
where Python is rejecting the octal-incompatible digit.
There doesn't seem to be anything provided via __future__ to
allow me to get the Py3K behavior---it would have to be built-in
to Python in some manner, since it requires a change to the lexer
at least.
Is anyone aware of how I could protect my users from getting the
wrong job in cases like this? At the moment the best I can think
of is to change that API so it take a string instead of an int.
At the moment the best I can think of is to change that API so it take a string instead of an int.
Yes, and I think this is a reasonable option given the situation.
Another option would be to make sure that all your job numbers contain at least one digit greater than 7 so that adding the leading zero will give an error immediately instead of an incorrect result, but that seems like a bigger hack than using strings.
A final option could be to educate your users. It will only take five minutes or so to explain not to add the leading zero and what can happen if you do. Even if they forget or accidentally add the zero due to old habits, they are more likely to spot the problem if they have heard of it before.
Perhaps you could take the input as a string, strip leading zeros, then convert back to an int?
test = "001234505"
test = int(test.lstrip("0")) # 1234505