Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 333
  • Last Modified:

xor crypting filename, can't be save on Windows os

Hi,

I try to find a way to crypt the filenames only of files presents on a directory
and save these renamed files on disk, it appears that windows doesn't like
special characters and python gives error message when executing this code:

import os
import time
#1 
from itertools import izip, cycle
 
def xor_crypt_string(data, key):
    return ''.join(chr(ord(x) ^ ord(y)) for (x,y) in izip(data, cycle(key)))


my_key= "firefly"


for f in  os.listdir(dir):
    filename = f
    str_filename = str(filename)
	#1
    encrypted = xor_crypt_string(str_filename, my_key)
    print ("current file = %s   >> encrypt = %s " % (str_filename, encrypted))
    os.rename(dir + "\\" + f, dir + "\\"+str(encrypted)+".txt")
    
raw_input()

Open in new window


The error message is:

current file = doc_letter.txt   >> encrypt = ¿¿¿¿¿W¿¿
renaming...
Traceback (most recent call last):
  File "C:\test_encrypt_rename\
encryp_filename.py", line 66, in <module>
    os.rename(dir + "\\" + f, dir + "\\"+str(encrypted))
WindowsError: [Error 123] filename syntax , ddirectories or volumes not correct


So what is best way to xor filename of a file (no contain) and save this renamed file so that
we can back to original name with the same key ?

What if using one character key ?

Thanks
0
Develprog
Asked:
Develprog
  • 7
  • 6
  • 2
2 Solutions
 
Dave BaldwinFixer of ProblemsCommented:
From http://windows.microsoft.com/en-us/windows/file-names-extensions-faq#1TC=windows-7 

You can't use any of the following characters in a file name: \ / ? : * " > < |

You also can't use any 'device' names with a ':' in it like 'COM1:' or 'PRN:'.

And it may be worse than that.  Windows uses 16-bit characters.  You might want to check to see what the numeric value is after XOR-ing a single character.  And if you still have 'short' or 8.3 filenames on your filesystem, they may prevent you from saving odd names.
0
 
DevelprogAuthor Commented:
Hi,


>> You can't use any of the following characters in a file name: \ / ? : * " > < |
So are any exotic unicode character permits?

The goal is to restore orignal name with the same key.
So it cannot be possible to crypt filename with xor encryption?
Could you help me ?


Thanks
0
 
Dave BaldwinFixer of ProblemsCommented:
The problem is that XOR produces results that can generate characters that aren't allowed.  I don't think it is a practical function for what you want.  Here is info on Character Sets for Microsoft Windows:

http://msdn.microsoft.com/en-us/library/windows/desktop/dd317743%28v=vs.85%29.aspx
0
Automating Your MSP Business

The road to profitability.
Delivering superior services is key to ensuring customer satisfaction and the consequent long-term relationships that enable MSPs to lock in predictable, recurring revenue. What's the best way to deliver superior service? One word: automation.

 
peprCommented:
Possibly, you should explain what is your goal. Should the process of renaming the file also reversible? Could the name be created "unreadable" also by other ways?
0
 
DevelprogAuthor Commented:
Yes it must be reversible,  so the goal is get back original filename with the same key that encoded it. So basically I think to XOR encryption but ...

One solution will be to encode the ascii filename string into hex and save the file with this name. Then the reverse decode process will get the ascii filename.

This works well:
import os
import time

for f in  os.listdir(dir):
	filename = f
	str_filename = str(filename)
	
	#case encoding the original ascii filename
	hexfromstring= str_filename.encode("hex")
	print ("%s -> encode -> %s " % (str_filename,hexfromstring))
	
	if (os.path.isfile(dir + "\\" + f)):
		os.rename(dir + "\\" + f, dir + "\\"+hexfromstring)
	
	#case geting back original ascii filename (str_filename being hex string)
	stringfromhex= str_filename.decode("hex")
	print ("decoded string is %s -> back to original -> %s " % (str_filename,stringfromhex))

	if(os.path.isfile(dir + "\\" + f)):
			print "renaming..."
			os.rename(dir + "\\" + f, dir + "\\"+stringfromhex)
	
raw_input()

Open in new window


There is no key but that can "crypt" a filename. Best would be the encoding/decoding operations processed with a password.

Is there another approach ?
0
 
peprCommented:
Frankly, I can see no reason to encrypt the filenames. The problem with conversion to hex is that the result is twice as long as the original. There is a limit for the path length in Windows. Theoretically, it can apply to your problem. In practice, it would probably work.

Anyway, you can use str.translate() of the standard string to shuffle the characters -- see http://docs.python.org/2/library/stdtypes.html?highlight=translate#str.translate. For that you need to generate two translation tables: one of encryption, the other for decryption. The forbidden characters (for paths) can be mapped to itself or to whatever.
0
 
DevelprogAuthor Commented:
Hi,

>>Frankly, I can see no reason to encrypt the filenames.

The reason is to avoid some curious people (not having much knowledge on computer)  to look at your personnal data in your computer, for example your encrypted text file cannot be give aby informations of its contain and not guess which type of file it is.

 
>> to  generate two translation tables: one of encryption, the other for decryption. The forbidden characters (for paths) can be mapped to itself or to whatever.

You mean sort of dictionnary, so no encryption key or a xor encryption followed by a dictionnary?  Could you give an example code ?

Thanks
0
 
peprCommented:
Here is a quick hack example of using the str.translate() method:
#!python3

# For the .translate(), we need the translation sequence for the 256 chars.
table = [chr(i) for i in range(256)]
print(''.join(table[:128]))             # just to display the lower part
print(ord('A'))
print(ord('Z'))
print(ord('a'))
print(ord('z'))

print(''.join(table[65:91]))            # A-Z is on those indices
print(''.join(table[97:123]))           # a-z is on those indices


print('-' * 70)

# Let's just reverse the alphabet character subsequences.
enc = table[:]                          # deep copy
enc[65:91] = reversed(table[65:91])     # in-place replacement by the reversed
print(''.join(enc[65:91]))              # A-Z

enc[97:123] = reversed(table[97:123])
print(''.join(enc[97:123]))             # a-z

print('-' * 70)

# Now having some text, use the string and the translation table to "encrypt".
s = 'some text'
print(s)
s2 = s.translate(enc)
print(s2)

# Here the same translation table can be used for decoding.
s3 = s2.translate(enc)
print(s3)

Open in new window

When executed, you should see:
c:\__Python\Develprog\Q_28365879>a.py
 ¿¿¿¿
¿¤¿¿¿¿¶§¿¿¿¿¿¿¿¿¿¿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]
^_`abcdefghijklmnopqrstuvwxyz{|}~¦
65
90
97
122
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
----------------------------------------------------------------------
ZYXWVUTSRQPONMLKJIHGFEDCBA
zyxwvutsrqponmlkjihgfedcba
----------------------------------------------------------------------
some text
hlnv gvcg
some text

Open in new window


Notice that here the same table could be used both for "encryption" and "decryption". When the translate table is created differently, you may need two tables for the two directions.
0
 
DevelprogAuthor Commented:
Hi,

Good example of encryption too but I suppose s.translate  is available on python 3 only, so what to do with python 2.7.  ?

Because when running program , I have this error message:
some text
Traceback (most recent call last):
  File "C:\Users\Ali w7\Desktop\EXAMPLE-PROJET\test_en
py", line 29, in <module>
    s2 = s.translate(enc)
TypeError: expected a character buffer object

Open in new window



But if string contains upper and lower letter, will it be ok with a table like this:

table[65:123]?
0
 
peprCommented:
Python 2.7 also supports the str.translate() -- see http://docs.python.org/2.7/library/stdtypes.html#str.translate. There may be some problem with types. I will check when being at a normal computer. The example should work also with mixed case letters. The lower-case and upper-case sequences were reversed separately, but the translation table must contain 256 characters.
0
 
peprCommented:
Here is the example fixed for Python 2.7. See the comments:
#!python2.7

# For the .translate(), we need the translation sequence for the 256 chars.
table = [chr(i) for i in range(256)]
print ''.join(table[:128])             # just to display the lower part

# Let's just reverse the alphabet character subsequences.
enc = table[:]                          # deep copy
enc[65:91] = reversed(table[65:91])     # in-place replacement by the reversed
enc[97:123] = reversed(table[97:123])

print('-' * 70)

# Python 3 accepts the enc also as list of characters. Python 2.7 requires
# the string of all 256 characters. Let's convert it and assign it to the same
# variable.
enc = ''.join(enc)

# Now having some text, use the string and the translation table to "encrypt".
s = 'sOmE MIXED case Text'
print(s)
s2 = s.translate(enc)
print(s2)

# Here the same translation table can be used for decoding.
s3 = s2.translate(enc)
print(s3)

Open in new window

It prints
c:\__Python\Develprog\Q_28365879>b.py
 ¿¿¿¿
¿¤¿¿¿¿¶§¿¿¿¿¿¿¿¿¿¿ !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]
^_`abcdefghijklmnopqrstuvwxyz{|}~¦
----------------------------------------------------------------------
sOmE MIXED case Text
hLnV NRCVW xzhv Gvcg
sOmE MIXED case Text

Open in new window

0
 
DevelprogAuthor Commented:
Hi,

Thank you pepr, unfortunatly for filename xor crypto is not suitable.
But anyway we have others solutions although these encryptions can be
decrypted if script file found.
0
 
peprCommented:
The above is not a XOR crypto. But, as others also said, this is not "crypto" at all. It is just obfuscation. This means that you try to hide it by not telling the others how you hide it. Once the others learn how it was hidden, they can get it easily -- this holds also for XOR.

True cryptography gives you tools to really hide the content even though the others know the way how it was hidden. The only way to get it back is based on the knowledge of the key. Without the key, it is impossible (unless you have the NSA equipment ;)

You can encrypt a partition of your disk or the content of your flash-disk. Or you can zip the files with a password.
0
 
DevelprogAuthor Commented:
Thank you,

right anyway xor encryption has too key but a easy one :) because not hide like in true cryptography.
0
 
DevelprogAuthor Commented:
I don't select my own repsonse as best. I try to give multiple solutions but vote system doesn't allow it or  i can not do it.
So my points is :   200 for pepr
                             100 for me

And the grade solution is quite very good but there was no a real example with xor encryption but  with sr.translate() but it is still good other approach good explained and with complete code example.

Thanks
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

  • 7
  • 6
  • 2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now