木村  直子

木村 直子

1682600402

为特定用户授予对 Linux 中文件夹的写入权限

为特定用户写入文件夹权限。在本教程中,您将学习如何在 Linux 中为用户授予对文件夹的写入权限。

在开始之前,了解 Linux 中文件权限的基础知识很重要。共有三种类型的权限:读取 (r)、写入 (w) 和执行 (x)。这些权限分配给三种不同类型的用户:文件的所有者、所有者所属的组和所有其他用户。

如何在 Linux 中为用户授予对文件夹的写入权限

要为特定用户授予对文件夹的写权限,您需要按照以下步骤操作:

  • 第 1 步:确定文件夹的所有者和组
  • 第 2 步:将用户添加到组
  • 第 3 步:更改文件夹的权限
  • 第 4 步:验证权限

第 1 步:确定文件夹的所有者和组

要查看文件夹的所有者和所属组,可以使用以下命令:

ls -l foldername

这将显示文件夹的详细信息,包括所有者和组。

第 2 步:将用户添加到组

要授予用户写权限,您可以将用户添加到文件夹的组中。为此,您可以使用以下命令:

sudo usermod -a -G groupname username

将“groupname”替换为拥有该文件夹的组的名称,将“username”替换为您要授予写入权限的用户的名称。

第 3 步:更改文件夹的权限

将用户添加到组后,您可以更改文件夹的权限以授予组写入权限。为此,您可以使用以下命令:

sudo chmod g+w foldername

此命令更改文件夹的权限以允许组的写访问权限。

第 4 步:验证权限

要验证权限是否已成功更改,您可以使用以下命令:

ls -l foldername

这将显示文件夹的详细信息,包括新权限。

以下是有关如何在 Linux 中为用户授予对文件夹的写入权限的一些常见问题解答

  1. 为什么我需要为用户授予对 Linux 中的文件夹的写权限?
    • 答:如果您希望用户能够在文件夹中修改或创建文件,您可能需要为该用户授予对 Linux 中的文件夹的写入权限。没有写权限,用户将只能读取文件夹中的文件。
  2. 我可以为多个用户授予对文件夹的写权限吗?
    • A: 是的,您可以将多个用户添加到拥有该文件夹的组中,然后授予该组写权限。这将为组中的所有用户提供对该文件夹的写入权限。
  3. 如何为用户删除文件夹的写入权限?
    • 答:要取消用户对文件夹的写权限,您可以从拥有该文件夹的组中删除该用户,或者更改文件夹的权限以取消该组的写权限。
  4. 如果我为所有用户授予对文件夹的写权限,会发生什么情况?
    • 答:如果您为所有用户授予对文件夹的写入权限,则系统上的任何用户都可以修改或创建文件夹内的文件。这可能存在安全风险,因此只向需要它的用户授予写入权限很重要。
  5. 我可以在不更改整个组的权限的情况下为用户授予对文件夹的写入权限吗?
    • 答:是的,您可以使用访问控制列表 (ACL) 为特定用户授予对文件夹的写入权限,而无需更改整个组的权限。这是一个更高级的主题,需要了解 ACL。
  6. linux下如何查看文件夹的当前权限?
    • A:Linux下可以使用ls -l命令查看当前文件夹的权限。这将显示所有者、组和其他人的权限,以及有关文件夹中文件的其他详细信息。
  7. 我可以在不使用命令行的情况下为用户授予对文件夹的写权限吗?
    • 答:是的,Linux 中的大多数文件管理器都可以修改文件和文件夹的权限。您可以使用文件管理器导航到要修改的文件夹,然后右键单击该文件夹并选择“属性”或“权限”以更改权限。
  8. 为用户授予对文件夹的写权限有哪些风险?
    • 答:如果用户修改或删除文件夹中的重要文件,则为用户授予对文件夹的写入权限可能存在安全风险。重要的是只给需要它的用户写权限并定期备份重要文件。
  9. 如何为远程服务器上的用户授予对文件夹的写权限?
    • A:您可以使用SSH 连接到远程服务器,然后使用相同的命令将用户添加到组并更改文件夹的权限。您将需要具有访问远程服务器所需的权限和凭据。
  10. 我可以为用户授予对文件夹的写入权限而不授予他们对系统上其他文件夹的访问权限吗?
    • A: 是的,您可以为用户创建一个单独的组,并授予该组对文件夹的写入权限。这将允许用户修改该文件夹中的文件,而无需授予他们访问系统上其他文件夹的权限。

结论

总之,在 Linux 中为用户授予对文件夹的写权限涉及识别文件夹的所有者和组、将用户添加到组、更改文件夹的权限以允许组的写访问以及验证权限。通过执行这些步骤,您可以轻松地为特定用户授予对 Linux 中的文件夹的写入权限。

文章原文出处:https: //www.tutsmake.com/

#linux #folder #write #permission 

为特定用户授予对 Linux 中文件夹的写入权限
Bongani  Ngema

Bongani Ngema

1682593033

Give Write Permission to a Folder in Linux for Specific User

To write permission to a folder for a specific user. In this tutorial, you will learn how to grant write permission to a folder in Linux for a user.

Before you start, it is important to understand the basics of file permissions in Linux. There are three types of permissions: read (r), write (w), and execute (x). These permissions are assigned to three different types of users: the owner of the file, the group to which the owner belongs, and all other users.

How to Give Write Permission to a Folder in Linux for User

To grant write permission to a folder for a specific user, you need to follow the following steps:

  • Step 1: Identify the owner and group of the folder
  • Step 2: Add the user to the group
  • Step 3: Change the permissions of the folder
  • Step 4: Verify the permissions

Step 1: Identify the owner and group of the folder

To view the owner and group of a folder, you can use the following command:

ls -l foldername

This will display the details of the folder, including the owner and group.

Step 2: Add the user to the group

To grant write permission to a user, you can add the user to the group of the folder. To do this, you can use the following command:

sudo usermod -a -G groupname username

Replace “groupname” with the name of the group that owns the folder, and “username” with the name of the user that you want to grant write permission to.

Step 3: Change the permissions of the folder

Once the user has been added to the group, you can change the permissions of the folder to grant write permission to the group. To do this, you can use the following command:

sudo chmod g+w foldername

This command changes the permissions of the folder to allow write access for the group.

Step 4: Verify the permissions

To verify that the permissions have been changed successfully, you can use the following command:

ls -l foldername

This will display the details of the folder, including the new permissions.

Here are some faqs on How to Give Write Permission to a Folder in Linux for User

  1. Why would I need to give write permission to a folder in Linux for a user?
    • A: You might need to give write permission to a folder in Linux for a user if you want that user to be able to modify or create files within the folder. Without write permission, the user will only be able to read the files in the folder.
  2. Can I give write permission to a folder for multiple users?
    • A: Yes, you can add multiple users to the group that owns the folder and then grant write permission to the group. This will give all the users in the group write access to the folder.
  3. How do I remove write permission from a folder for a user?
    • A: To remove write permission from a folder for a user, you can remove the user from the group that owns the folder or change the permissions of the folder to remove write access for the group.
  4. What happens if I give write permission to a folder for all users?
    • A: If you give write permission to a folder for all users, any user on the system will be able to modify or create files within the folder. This can be a security risk, so it’s important to only give write permission to users who need it.
  5. Can I give write permission to a folder for a user without changing the permissions for the entire group?
    • A: Yes, you can use access control lists (ACLs) to give write permission to a folder for a specific user without changing the permissions for the entire group. This is a more advanced topic and requires knowledge of ACLs.
  6. How can I view the current permissions of a folder in Linux?
    • A: You can use the command “ls -l” to view the current permissions of a folder in Linux. This will display the permissions for the owner, group, and others, as well as other details about the files in the folder.
  7. Can I give write permission to a folder for a user without using the command line?
    • A: Yes, most file managers in Linux have the ability to modify permissions for files and folders. You can use the file manager to navigate to the folder you want to modify and then right-click on the folder and select “Properties” or “Permissions” to change the permissions.
  8. What are the risks of giving write permission to a folder for a user?
    • A: Giving write permission to a folder for a user can be a security risk if the user modifies or deletes important files in the folder. It’s important to only give write permission to users who need it and to regularly back up important files.
  9. How can I give write permission to a folder for a user on a remote server?
    • A: You can use SSH to connect to the remote server and then use the same commands to add the user to the group and change the permissions of the folder. You will need to have the necessary permissions and credentials to access the remote server.
  10. Can I give write permission to a folder for a user without giving them access to other folders on the system?
    • A: Yes, you can create a separate group for the user and give that group write permission to the folder. This will allow the user to modify files in that folder without giving them access to other folders on the system.

Conclusion

In conclusion, granting write permission to a folder in Linux for a user involves identifying the owner and group of the folder, adding the user to the group, changing the permissions of the folder to allow write access for the group, and verifying the permissions. By following these steps, you can easily grant write permission to a folder in Linux for a specific user.

Original article source at: https://www.tutsmake.com/

#linux #folder #write #permission 

Give Write Permission to a Folder in Linux for Specific User

Как использовать шифр Цезаря в Python

Криптография имеет дело с шифрованием или кодированием части информации (в виде обычного текста) в форму, которая выглядит бессвязно и не имеет большого смысла на обычном языке.
Это закодированное сообщение (также называемое  зашифрованным текстом ) затем может быть декодировано обратно в обычный текст предполагаемым получателем с использованием метода декодирования (часто вместе с закрытым ключом), сообщенного конечному пользователю.

Шифр Цезаря — один из старейших методов шифрования, на котором мы сосредоточимся в этом руководстве, и реализуем его в Python.
Несмотря на то, что шифр Цезаря является  очень слабым методом шифрования  и редко используется сегодня, мы делаем это руководство, чтобы познакомить наших читателей, особенно новичков, с шифрованием.
Считайте это «Hello World» криптографии.

Что такое шифр Цезаря?

Шифр Цезаря — это тип шифра замены , в котором каждая буква в открытом тексте заменяется другой буквой в некоторых фиксированных позициях от текущей буквы в алфавите.

Например, если мы сдвинем каждую букву на три позиции вправо, каждая буква в нашем открытом тексте будет заменена буквой на три позиции справа от буквы в открытом тексте.
Давайте посмотрим на это в действии — давайте зашифруем текст «HELLO WORLD», используя сдвиг вправо на 3.

Таким образом, буква H будет заменена на K, E будет заменена на H и так далее. Последним зашифрованным сообщением для  HELLO WORLD  будет  KHOOR ZRUOG. Эта тарабарщина не имеет смысла, не так ли?

Обратите внимание, что буквы на ребре, т. е. X, Y, Z, переходят друг в друга и заменяются на A, B, C соответственно в случае сдвига вправо. Точно так же буквы в начале — A, B, C и т. д. — будут оборачиваться при сдвигах влево.

Правило  шифрования шифра Цезаря  может быть выражено математически как:

c = (x + n) % 26

Где c — закодированный символ, x — фактический символ, а n — количество позиций, на которые мы хотим сдвинуть символ x. Мы берем мод с 26, потому что в английском алфавите 26 букв.

Шифр Цезаря на Python

Прежде чем мы углубимся в определение функций для процесса шифрования и дешифрования Caesar Cipher в Python, мы сначала рассмотрим две важные функции, которые мы будем широко использовать в процессе — chr() и  ord  () .
Важно понимать, что алфавит, каким мы его знаем, по-разному хранится в памяти компьютера. Компьютер сам по себе не понимает ни алфавита нашего английского языка, ни других символов.

Каждый из этих символов представлен в памяти компьютера с помощью числа, называемого кодом ASCII (или его расширением — Unicode) символа, который представляет собой 8-битное число и кодирует почти все символы английского языка, цифры и знаки препинания.
Например, буква «А» в верхнем регистре представлена ​​числом 65, «В» — числом 66 и так далее. Точно так же представление символов нижнего регистра начинается с числа 97.

Поскольку возникла необходимость включать больше символов и символов других языков, 8-битного оказалось недостаточно, поэтому был принят новый стандарт —  Unicode  , который представляет все символы, используемые в мире, с помощью 16-битного.
ASCII является подмножеством Unicode, поэтому кодировка символов ASCII остается такой же в Unicode. Это означает, что «A» по-прежнему будет представляться с использованием числа 65 в Unicode.
Обратите внимание, что специальные символы, такие как пробел «», табуляция «\t», символы новой строки «\n» и т. д., также представлены в памяти своим Unicode.

Мы рассмотрим две встроенные в Python функции, которые используются для поиска Unicode-представления символа и наоборот.

Функция ord()

Вы можете использовать метод ord() для преобразования символа в его числовое представление в Unicode. Он принимает один символ и возвращает число, представляющее его Unicode. Давайте посмотрим на пример.

c_unicode = ord("c")

A_unicode = ord("A")

print("Unicode of 'c' =", c_unicode)

print("Unicode of 'A' =", A_unicode)

Выход:

Функция хр()

Точно так же, как мы могли бы преобразовать символ в его числовой Unicode, используя метод ord(), мы делаем обратное, т.е. находим символ, представленный числом, используя метод chr().
Метод chr() принимает число, представляющее Unicode символа, и возвращает фактический символ, соответствующий числовому коду.
Давайте сначала рассмотрим несколько примеров:

character_65 = chr(65)

character_100 = chr(100)

print("Unicode 65 represents", character_65)

print("Unicode 100 represents", character_100)

character_360 = chr(360)

print("Unicode 360 represents", character_360)

Выход:

Обратите внимание, что немецкая буква  Ü  (умлаут U) также представлена ​​в Unicode числом 360.

Мы также можем применить цепную операцию (ord, за которой следует chr), чтобы вернуть исходный символ.

c = chr(ord("Ũ"))

print(c)

Выход: Ũ

Шифрование заглавных букв

Теперь, когда мы познакомились с двумя основными методами, которые будем использовать, давайте реализуем технику шифрования заглавных букв в Python. Мы зашифруем в тексте только заглавные буквы, а остальные оставим без изменений.
Давайте сначала рассмотрим пошаговый процесс шифрования заглавных букв:

  1. Определите значение сдвига, т. е. количество позиций, на которые мы хотим сместиться от каждого символа.
  2. Перебрать каждый символ обычного текста:
    1. Если символ в верхнем регистре:
      1. Вычислить положение/индекс символа в диапазоне 0-25.
      2. Выполните  положительный сдвиг  , используя операцию по модулю.
      3. Найдите персонажа в новой позиции.
      4. Замените текущую заглавную букву этим новым символом.
    2. В противном случае, если символ не в верхнем регистре, сохраните его без изменений.

Давайте теперь посмотрим на код:

shift = 3 # defining the shift count

text = "HELLO WORLD"

encryption = ""

for c in text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the shift
        new_index = (c_index + shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to encrypted string
        encryption = encryption + new_character

    else:

        # since character is not uppercase, leave it as it is
        encryption += c
        
print("Plain text:",text)

print("Encrypted text:",encryption)

Выход:

Как мы видим, зашифрованный текст для «HELLO WORLD» — «KHOOR ZRUOG», и он соответствует тому, который мы получили вручную в разделе «Введение».
Кроме того, этот метод не шифрует символ пробела, и в зашифрованной версии он остается пробелом.

Расшифровка заглавных букв

Теперь, когда мы разобрались с шифрованием заглавных букв обычного текста с помощью Ceaser Cipher, давайте посмотрим, как мы будем расшифровывать зашифрованный текст в обычный текст.

Ранее мы рассмотрели математическую формулировку процесса шифрования. Давайте теперь проверим то же самое для процесса расшифровки.

x = (c - n) % 26

Смысл обозначений остается тем же, что и в предыдущей формуле.
Если какое-либо значение после вычитания становится отрицательным, об этом позаботится оператор по модулю , и он обернет его.

Давайте посмотрим на пошаговую реализацию процесса дешифрования, который будет более или менее обратным шифрованию:

  • Определить количество смен
  • Перебрать каждый символ в зашифрованном тексте:
    • Если символ является заглавной буквой:
      1. Вычислить положение/индекс символа в диапазоне 0-25.
      2. Выполните  отрицательный сдвиг  , используя операцию по модулю.
      3. Найдите персонажа в новой позиции.
      4. Замените текущую зашифрованную букву этим новым символом (который также будет заглавной буквой).
      5. В противном случае, если символ не заглавный, оставьте его без изменений.

Давайте напишем код для вышеуказанной процедуры:

shift = 3 # defining the shift count

encrypted_text = "KHOOR ZRUOG"

plain_text = ""

for c in encrypted_text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the negative shift
        new_index = (c_index - shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to plain string
        plain_text = plain_text + new_character

    else:

        # since character is not uppercase, leave it as it is
        plain_text += c

print("Encrypted text:",encrypted_text)

print("Decrypted text:",plain_text)

Выход:

Обратите внимание, как мы успешно восстановили исходный текст «HELLO WORLD» из его зашифрованной формы.

Шифрование цифр и знаков препинания

Теперь, когда мы увидели, как мы можем кодировать и декодировать заглавные буквы английского алфавита с помощью шифра Цезаря, возникает важный вопрос: а как насчет других символов?
Как насчет чисел? А как насчет специальных символов и знаков препинания?

Что ж, исходный алгоритм шифра Цезаря не должен был иметь дело ни с чем, кроме 26 букв алфавита — ни в верхнем, ни в нижнем регистре.
Таким образом, типичный шифр Цезаря не будет шифровать знаки препинания или цифры, а будет преобразовывать все буквы в нижний или верхний регистр и кодировать только эти символы.

Но мы всегда можем расширить существующее хорошее решение и настроить его в соответствии с нашими потребностями — это верно для любой задачи в разработке программного обеспечения.
Итак, мы попробуем закодировать прописные и строчные буквы так, как мы это делали в предыдущем разделе, мы пока проигнорируем знаки препинания, а затем также будем кодировать числа в тексте.

Для чисел мы можем выполнить шифрование одним из двух способов:

  1. Сдвиньте цифровое значение на ту же величину, что и буквы алфавита, т. е. для сдвига на 3 — цифра 5 станет 8, 2 станет 5, 9 станет 2 и так далее.
  2. Сделайте числа частью алфавита, т. е. после z или Z будут следовать 0,1,2. до 9, и на этот раз наш делитель для операции по модулю будет 36 вместо 26.

Мы реализуем наше решение, используя первую стратегию. Кроме того, на этот раз мы реализуем наше решение как функцию, которая принимает значение сдвига (которое служит ключом в шифре Цезаря) в качестве параметра.
Мы реализуем 2 функции —  cipher_encrypt()  и  cipher_decrypt()
Давайте запачкаем руки!

Решение

# The Encryption Function
def cipher_encrypt(plain_text, key):

    encrypted = ""

    for c in plain_text:

        if c.isupper(): #check if it's an uppercase character

            c_index = ord(c) - ord('A')

            # shift the current character by key positions
            c_shifted = (c_index + key) % 26 + ord('A')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.islower(): #check if its a lowecase character

            # subtract the unicode of 'a' to get index in [0-25) range
            c_index = ord(c) - ord('a') 

            c_shifted = (c_index + key) % 26 + ord('a')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_new = (int(c) + key) % 10

            encrypted += str(c_new)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            encrypted += c

    return encrypted

# The Decryption Function
def cipher_decrypt(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.isupper(): 

            c_index = ord(c) - ord('A')

            # shift the current character to left by key positions to get its original position
            c_og_pos = (c_index - key) % 26 + ord('A')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_og = (int(c) - key) % 10

            decrypted += str(c_og)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            decrypted += c

    return decrypted

Теперь, когда мы определили наши две функции, давайте сначала воспользуемся функцией шифрования, чтобы зашифровать секретное сообщение, которым друг делится через текстовое сообщение со своим приятелем.

plain_text = "Mate, the adventure ride in Canberra was so much fun, We were so drunk we ended up calling 911!"

ciphertext = cipher_encrypt(plain_text, 4)

print("Plain text message:\n", plain_text)

print("Encrypted ciphertext:\n", ciphertext)

Выход:

Обратите внимание, что все, кроме знаков препинания и пробелов, зашифровано.

Теперь давайте посмотрим на зашифрованный текст, который полковник Ник Фьюри отправлял на свой пейджер: « Sr xli gsyrx sj 7, 6, 5 – Ezirkivw Ewwiqfpi! '
Оказывается, это шифротекст Цезаря, и, к счастью, мы получили ключ к этому шифротексту!
Посмотрим, сможем ли мы раскопать скрытое сообщение.

ciphertext = "Sr xli gsyrx sj 7, 6, 5 - Ezirkivw Ewwiqfpi!"

decrypted_msg = cipher_decrypt(ciphertext, 4)

print("The cipher text:\n", ciphertext)

print("The decrypted message is:\n",decrypted_msg)

Выход:

Так держать, Мстители!

Использование таблицы поиска

На этом этапе мы поняли процесс шифрования и дешифрования шифра Цезаря и реализовали его в Python.

Теперь мы рассмотрим, как его можно сделать более эффективным и гибким. В частности, мы сосредоточимся на том, как мы можем избежать повторных вычислений смещенных позиций для каждой буквы в тексте в процессе шифрования и дешифрования, заранее
построив таблицу поиска 

Мы также рассмотрим, как мы можем использовать любой набор определяемых пользователем символов, а не только буквы алфавита, в нашем процессе шифрования.
Мы также объединим процесс шифрования и дешифрования в одну функцию и примем в качестве параметра, какой из двух процессов пользователь хочет выполнить.

Что такое таблица поиска?

Таблица поиска — это просто сопоставление исходных символов и символов, в которые они должны быть преобразованы, в зашифрованном виде.
До сих пор мы перебирали каждую букву в строке и вычисляли их сдвинутые позиции.
Это неэффективно, потому что наш набор символов ограничен, и большинство из них встречаются в строке более одного раза.
Таким образом, вычисление их зашифрованной эквивалентности каждый раз, когда они появляются, неэффективно, и это становится дорогостоящим, если мы шифруем очень длинный текст с сотнями тысяч символов в нем.

Мы можем избежать этого, вычислив сдвинутые позиции каждого из символов в нашем наборе символов только один раз перед началом процесса шифрования.
Таким образом, если имеется 26 прописных и 26 строчных букв, нам потребуется всего 52 вычисления один раз и некоторое пространство в памяти для хранения этого сопоставления.
Затем во время процесса шифрования и дешифрования все, что нам нужно будет сделать, это выполнить «поиск» в этой таблице — операция, которая быстрее, чем выполнение операции по модулю каждый раз.

Создание таблицы поиска

Строковый модуль Python   предоставляет простой способ не только создать таблицу поиска, но и преобразовать любую новую строку на основе этой таблицы.

Давайте возьмем пример, когда мы хотим создать таблицу первых пяти строчных букв и их индексов в алфавите.
Затем мы использовали бы эту таблицу для перевода строки, в которой каждое из вхождений «a», «b», «c», «d» и «e» заменено на «0», «1», «2». , «3» и «4» соответственно; а остальные символы не тронуты.

Мы будем использовать   функцию  maketrans() модуля str  для создания таблицы.
Этот метод принимает в качестве первого параметра строку символов, для которой требуется перевод, и другой строковый параметр той же длины, который содержит сопоставленные символы для каждого символа в первой строке.

Давайте создадим таблицу для простого примера.

table = str.maketrans("abcde", "01234")

Таблица представляет собой словарь Python, в котором значения Unicode символов используются в качестве ключей, а соответствующие им сопоставления — в качестве значений.
Теперь, когда у нас есть готовая таблица, мы можем преобразовать строки любой длины, используя эту таблицу.
К счастью, переводом также занимается другая функция модуля str, которая называется  translate.

Давайте используем этот метод для преобразования нашего текста с помощью нашей таблицы.

text = "Albert Einstein, born in Germany, was a prominent theoretical physicist."

translated = text.translate(table)

print("Original text:/n", text)

print("Translated text:/n", translated)

Выход:

Как видите, каждый экземпляр первых пяти строчных букв заменен их относительными индексами.

Теперь мы воспользуемся той же техникой для создания таблицы поиска для Caesar Cipher на основе предоставленного ключа.

Внедрение шифрования

Давайте создадим функцию  caesar_cipher()  , которая принимает строку для шифрования/расшифровки, «набор символов», показывающий, какие символы в строке должны быть зашифрованы (по умолчанию это строчные буквы),
ключ и логическое значение, показывающее, если расшифровка выполнил или иным образом (шифрование).

import string

def cipher_cipher_using_lookup(text,  key, characters = string.ascii_lowercase, decrypt=False):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    table = str.maketrans(characters, characters[key:]+characters[:key])
    
    translated_text = text.translate(table)
    
    return translated_text

Теперь это одна мощная функция!

Вся операция смещения была сведена к операции нарезки .
Также мы используем  атрибут string.ascii_lowercase  — это строка символов от «a» до «z».
Еще одна важная особенность, которую мы здесь добились, заключается в том, что одна и та же функция выполняет как шифрование, так и дешифрование; это можно сделать, изменив значение параметра «ключ».
Операция нарезки вместе с этим новым ключом гарантирует, что набор символов был сдвинут влево — то, что мы делаем при расшифровке шифротекста Цезаря со сдвигом вправо.

Давайте проверим, работает ли это, используя более ранний пример.
Мы будем шифровать только заглавные буквы текста и снабдим их параметром 'characters'.
Зашифруем текст: «HELLO WORLD! Добро пожаловать в мир криптографии!»

text = "HELLO WORLD! Welcome to the world of Cryptography!"

encrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=False)

print(encrypted)

Выход:

Проверьте, как часть «ХОР ЗРУОГ» соответствует шифрованию «HELLO WORLD» с ключом 3 в нашем первом примере.
Также обратите внимание, что мы указываем набор символов в виде прописных букв, используя  string.ascii_uppercase.

Мы можем проверить, правильно ли работает расшифровка, используя тот же зашифрованный текст, который мы получили в нашем предыдущем результате.
Если мы сможем восстановить исходный текст обратно, это означает, что наша функция работает отлично.

text = "KHOOR ZRUOG! Zelcome to the world of Fryptography!"

decrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=True)

print(decrypted)

Выход:

Обратите внимание, как мы установили для параметра ' decrypt'  в нашей функции значение True.
Поскольку мы восстановили исходный текст обратно, это признак того, что наш алгоритм шифрования-дешифрования с использованием таблицы поиска работает хорошо!

Давайте теперь посмотрим, сможем ли мы  расширить набор символов,  включив в него не только строчные и прописные буквы, но также цифры и знаки препинания.

character_set = string.ascii_lowercase + string.ascii_uppercase + string.digits + " "+ string.punctuation

print("Extended character set:\n", character_set)

plain_text = "My name is Dave Adams. I am living on the 99th street. Please send the supplies!"

encrypted = cipher_cipher_using_lookup(plain_text, 5, character_set, decrypt=False)

print("Plain text:\n", plain_text)

print("Encrypted text:\n", encrypted)

Выход:

Здесь мы включили все символы, которые мы обсуждали до сих пор (включая пробел), в кодируемый набор символов.
В результате все (даже пробелы) в нашем простом тексте было заменено другим символом!
Единственная разница здесь в том, что перенос не происходит отдельно для строчных или прописных символов, а происходит в целом для всего набора символов.
Это означает, что «Y» со сдвигом на 3 не станет «B», а будет закодирован в «1».

Отрицательный сдвиг

До сих пор мы делали «положительные» сдвиги или «правильные сдвиги» символов в процессе шифрования. И процесс расшифровки того же самого включал «отрицательный» сдвиг или «сдвиг влево» символов.
Но что, если мы хотим выполнить процесс шифрования с отрицательным сдвигом? Изменится ли наш алгоритм шифрования-дешифрования?
Да, будет, но незначительно. Единственное изменение, которое нам нужно для сдвига влево, это сделать знак ключа отрицательным, остальная часть процесса останется прежней и приведет к результату сдвига влево в шифровании и сдвига вправо в процессе дешифрования.

Давайте попробуем это, изменив нашу предыдущую функцию, добавив еще один параметр —  «shift_type»  в нашу функцию  cipher_cipher_using_lookup() .

import string

def cipher_cipher_using_lookup(text, key, characters = string.ascii_lowercase, decrypt=False, shift_type="right"):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    if shift_type=="left":

        # if left shift is desired, we simply inverse they sign of the key
        key = -key

    table = str.maketrans(characters, characters[key:]+characters[:key])

    translated_text = text.translate(table)

    return translated_text

Давайте протестируем этот модифицированный метод на простом тексте.

text = "Hello World !"

encrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = False, shift_type="left")

print("plain text:", text)

print("encrypted text with negative shift:",encrypted)

Выход:

Обратите внимание, как каждый из символов в нашем простом тексте был сдвинут влево на три позиции.
Давайте теперь проверим процесс расшифровки, используя ту же строку.

text = "Ebiil Tloia !"

decrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = True, shift_type="left")

print("encrypted text with negative shift:", text)

print("recovered text:",decrypted)

Выход:

Таким образом, мы могли зашифровать и расшифровать текст, используя таблицу поиска и отрицательный ключ.

Шифрование файлов

В этом разделе мы рассмотрим использование шифра Цезаря для шифрования файла.
Обратите внимание, что мы можем шифровать только текстовые файлы, а не двоичные файлы, потому что мы знаем набор символов для обычных текстовых файлов.
Таким образом, вы можете зашифровать файл, используя один из следующих двух подходов:

  1. Прочитайте весь файл в строку, зашифруйте строку и выгрузите ее в другой файл.
  2. Итеративно читать файл по одной строке за раз, шифровать строку и записывать ее в другой текстовый файл.

Мы выберем второй подход, потому что первый возможен только для небольших файлов, содержимое которых может легко поместиться в памяти.
Итак, давайте определим функцию, которая принимает файл и шифрует его с помощью шифра Цезаря со сдвигом вправо на 3. Мы будем использовать набор символов по умолчанию из строчных букв.

def fileCipher(fileName, outputFileName, key = 3, shift_type = "right", decrypt=False):

    with open(fileName, "r") as f_in:

        with open(outputFileName, "w") as f_out:

            # iterate over each line in input file
            for line in f_in:

                #encrypt/decrypt the line
                lineNew = cipher_cipher_using_lookup(line, key, decrypt=decrypt, shift_type=shift_type)

                #write the new line to output file
                f_out.write(lineNew)
                    
    print("The file {} has been translated successfully and saved to {}".format(fileName, outputFileName))

Функция принимает имя входного файла, имя выходного файла и параметры шифрования/дешифрования, которые мы видели в последнем разделе.

Давайте зашифруем файл « milky_way.txt » (имеет вступительный абзац страницы «Млечный путь» в Википедии ).
Мы выведем зашифрованный файл в « milky_way_encrypted.txt ».

Давайте зашифруем его, используя функцию, которую мы определили выше:

inputFile = "./milky_way.txt"

outputFile = "./milky_way_encrypted.txt"

fileCipher(inputFile, outputFile, key=3, shift_type="right", decrypt = False)

Выход:

Давайте проверим, как теперь выглядит наш зашифрованный файл ' milky_way_encrypted.txt ':

Tkh Mlonb Wdb lv wkh jdodab wkdw frqwdlqv rxu Srodu Sbvwhp, zlwk wkh qdph ghvfulelqj wkh jdodab'v dsshdudqfh iurp Eduwk: d kdcb edqg ri 
oljkw vhhq lq wkh qljkw vnb iruphg iurp vwduv wkdw fdqqrw eh lqglylgxdoob glvwlqjxlvkhg eb wkh qdnhg hbh.
Tkh whup Mlonb Wdb lv d...
...
...

Итак, наша функция правильно шифрует файл.
В качестве упражнения вы можете попробовать функцию расшифровки, передав путь к зашифрованному файлу в качестве входных данных и установив для параметра «расшифровать» значение «Истина».
Посмотрите, сможете ли вы восстановить исходный текст.

Убедитесь, что вы не передаете один и тот же путь к файлу как для ввода, так и для вывода, что может привести к нежелательным результатам, поскольку программа будет выполнять операции чтения и записи в одном и том же файле одновременно.

Несколько смен (шифр Виженера)

До сих пор мы использовали одно значение сдвига (ключ) для сдвига всех символов строк на один и тот же номер. позиций.
Мы также можем попробовать вариант этого, где мы будем использовать не одну клавишу, а последовательность клавиш для выполнения разных сдвигов в разных позициях в тексте.

Например, предположим, что мы используем последовательность из 4 клавиш: [1,5,2,3] С помощью этого метода наш 1-й символ в тексте будет сдвинут на одну позицию, второй символ будет сдвинут на пять позиций. ,
3-й символ на две позиции, 4-й символ на три позиции, затем снова 5-й символ будет сдвинут на одну позицию и так далее.
Это улучшенная версия шифра Цезаря, которая называется  шифром Виженера.

Давайте реализуем шифр Виженера.

def vigenere_cipher(text, keys, decrypt=False):

    # vigenere cipher for lowercase letters
    n = len(keys)

    translatedText =""

    i = 0 #used to record the count of lowercase characters processed so far

    # iterate over each character in the text
    for c in text:

        #translate only if c is lowercase
        if c.islower():

            shift = keys[i%n] #decide which key is to be used

            if decrypt == True:

                # if decryption is to be performed, make the key negative
                shift = -shift

            # Perform the shift operation
            shifted_c = chr((ord(c) - ord('a') + shift)%26 + ord('a'))

            translatedText += shifted_c

            i += 1

        else:

            translatedText += c
            
    return translatedText

Функция выполняет как шифрование, так и расшифровку, в зависимости от значения логического параметра 'decrypt'.
Мы ведем подсчет всех строчных букв, закодированных/декодированных, используя переменную i, мы используем ее с оператором по модулю, чтобы определить, какой ключ из списка будет использоваться следующим.
Обратите внимание, что мы сделали операцию сдвига очень компактной; это эквивалентно многоэтапному процессу преобразования между Unicode и символьными значениями и вычислению сдвига, который мы видели ранее.

Давайте проверим эту функцию, используя другой простой текст:

text = "we will call the first manned moon mission the Project Apollo"

encrypted_text = vigenere_cipher(text, [1,2,3])

print("Plain text:\n", text)

print("Encrypted text:\n", encrypted_text)

Выход:

Здесь мы выполняем шифрование с использованием ключей  [1,2,3]  и, как и ожидалось, первый символ «w» был сдвинут на одну позицию к «x»,
второй символ «e» был сдвинут на две позиции к 'г'; третий символ «w» сдвигается на три позиции в сторону «z».
Этот процесс повторяется с последующими символами.
Продолжайте и выполните процесс расшифровки с теми же ключами и посмотрите, сможете ли вы восстановить исходное выражение обратно.

Почему шифр Цезаря слаб?

Каким бы простым ни было понимание и применение шифра Цезаря, он позволяет любому без особых усилий разобраться в расшифровке.
Шифр Цезаря — это метод шифра подстановки, при котором мы заменяем каждый символ в тексте некоторым фиксированным символом.

Если кто-то определит регулярность и закономерность появления определенных символов в зашифрованном тексте, он быстро определит, что для шифрования текста использовался шифр Цезаря.
Как только вы убедитесь, что метод шифра Цезаря был использован для шифрования текста, восстановление исходного текста без владения ключом станет легкой прогулкой.
Простой алгоритм BruteForce вычисляет исходный текст за ограниченное время.

Атака грубой силы

Для взлома шифротекста, закодированного с помощью шифра Цезаря, достаточно попробовать все возможные ключи.
Это осуществимо, потому что может быть только ограниченное количество ключей, которые могут генерировать уникальный зашифрованный текст.

Например, если в зашифрованном тексте закодирован весь текст в нижнем регистре, все, что нам нужно сделать, это выполнить шаг расшифровки со значениями ключа от 0 до 25.
Даже если пользователь предоставил ключ больше 25, он будет создавать зашифрованный текст, который является такой же, как один из сгенерированных с использованием ключей от 0 до 25.

Давайте проверим зашифрованный текст, в котором закодированы все символы нижнего регистра, и посмотрим, сможем ли мы извлечь из него осмысленный текст с помощью атаки BruteForce.
Текст у нас на руках:

"ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

Давайте сначала определим функцию расшифровки, которая принимает зашифрованный текст и ключ и расшифровывает все строчные буквы.

def cipher_decrypt_lower(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        else:

            decrypted += c

    return decrypted

Теперь у нас есть текст, но мы не знаем ключ, т.е. значение сдвига. Давайте напишем атаку грубой силы, которая пробует все ключи от 0 до 25 и отображает каждую из расшифрованных строк:

cryptic_text = "ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

for i in range(0,26):

    plain_text = cipher_decrypt_lower(cryptic_text, i)

    print("For key {}, decrypted text: {}".format(i, plain_text))

Выход:

В выходных данных перечислены все строки, которые вы можете сгенерировать в результате расшифровки.
Если вы посмотрите внимательно, строка с ключом 14 является правильным английским выражением и, следовательно, является правильным выбором.

Теперь вы знаете, как взломать зашифрованный текст шифром Цезаря.
Мы могли бы использовать другие, более надежные варианты шифра Цезаря, такие как использование нескольких сдвигов (шифр Виженера), но даже в этих случаях решительные злоумышленники могут легко определить правильное расшифрование.
Таким образом, алгоритм шифрования Цезаря относительно намного слабее, чем современные алгоритмы шифрования.

Заключение

В этом руководстве мы узнали, что такое шифр Цезаря, как его легко реализовать на Python и как его реализацию можно дополнительно оптимизировать с помощью того, что мы называем «таблицами поиска».
Мы написали функцию Python для реализации универсального алгоритма шифрования/дешифрования Caesar Cipher, который принимает различные пользовательские данные в качестве параметра без каких-либо предположений.

Затем мы рассмотрели, как мы можем зашифровать файл с помощью шифра Цезаря, а затем как шифр Цезаря можно усилить с помощью нескольких сдвигов.
Наконец, мы рассмотрели, насколько уязвим Caesar Cipher к атакам BruteForce.

Оригинальный источник статьи: https://likegeeks.com/

#python #cryptography 

Как использовать шифр Цезаря в Python
津田  淳

津田 淳

1680841828

如何在 Python 中使用凯撒密码

密码学处理将一段信息(以纯文本形式)加密或编码成一种看起来乱码且在普通语言中毫无意义的形式。然后,预期接收者可以使用与最终用户通信的解码技术(通常连同私钥)将此编码消息(也称为密文)解码回纯文本. 

Caesar Cipher 是我们将在本教程中重点关注的最古老的加密技术之一,并将在 Python 中实现相同的技术。
虽然凯撒密码是一种 非常弱的加密技术 ,今天很少使用,但我们做这个教程是为了向我们的读者,尤其是新手介绍加密。
将其视为密码学的“Hello World”。

什么是凯撒密码?

凯撒密码是一种替换密码,其中明文中的每个字母在字母表中当前字母的某些固定位置被另一个字母替换。

例如,如果我们将每个字母向右移动三个位置,则纯文本中的每个字母都将被纯文本中该字母右侧三个位置的字母替换。
让我们看看实际效果——让我们使用右移 3 来加密文本“HELLO WORLD”。

所以字母 H 将被替换为 K,E 将被替换为 H,依此类推。HELLO WORLD的最终加密消息  将是 KHOOR ZRUOG。 那些胡言乱语没有意义,是吗?

请注意,在右移的情况下,边缘上的字母 X、Y、Z 环绕并分别由 A、B、C 替换。类似地,开头的字母 – A、B、C 等将在左移的情况下环绕。

凯撒 密码加密规则 可以用数学表示为:

c = (x + n) % 26

其中 c 是编码字符,x 是实际字符,n 是我们要将字符 x 移动的位置数。我们将 mod 与 26 一起使用,因为英文字母表中有 26 个字母。

Python 中的凯撒密码

在我们深入研究用 Python 定义凯撒密码的加密和解密过程的函数之前,我们将首先看一下我们将在该过程中广泛使用的两个重要函数 – chr() 和ord  (  )
重要的是要认识到我们所知道的字母表在计算机内存中的存储方式不同。计算机本身无法理解我们英语中的任何字母表或其他字符。

这些字符中的每一个都在计算机内存中使用称为字符的 ASCII 码(或其扩展名 - Unicode)的数字表示,这是一个 8 位数字,对几乎所有英语字符、数字和标点符号进行编码。
例如,大写字母“A”由数字 65 表示,“B”由 66 表示,依此类推。同样,小写字符的表示以数字 97 开头。

由于需要合并更多其他语言的符号和字符,8 位是不够的,因此采用了新的标准 -  Unicode ,它使用 16 位表示世界上使用的所有字符。
ASCII 是 Unicode 的一个子集,所以字符的 ASCII 编码在 Unicode 中保持不变。这意味着“A”仍将使用 Unicode 中的数字 65 表示。
请注意,像空格“”、制表符“\t”、换行符“\n”等特殊字符在内存中也由它们的 Unicode 表示。

我们将查看 Python 中的两个内置函数,它们用于查找字符的 Unicode 表示形式,反之亦然。

ord() 函数

您可以使用 ord() 方法将字符转换为 Unicode 中的数字表示形式。它接受单个字符并返回代表其 Unicode 的数字。让我们看一个例子。

c_unicode = ord("c")

A_unicode = ord("A")

print("Unicode of 'c' =", c_unicode)

print("Unicode of 'A' =", A_unicode)

输出:

chr() 函数

就像我们如何使用 ord() 方法将字符转换为其数字 Unicode 一样,我们做相反的事情,即使用 chr() 方法找到由数字表示的字符。
chr() 方法接受一个表示字符 Unicode 的数字,并返回与数字代码对应的实际字符。
我们先来看几个例子:

character_65 = chr(65)

character_100 = chr(100)

print("Unicode 65 represents", character_65)

print("Unicode 100 represents", character_100)

character_360 = chr(360)

print("Unicode 360 represents", character_360)

输出:

请注意德语字母 Ü  (U 元音变音)在 Unicode 中如何由数字 360 表示。

我们还可以应用链式操作(ord 后跟 chr)来取回原始字符。

c = chr(ord("Ũ"))

print(c)

输出:×

大写字母加密

现在我们了解了我们将使用的两种基本方法,让我们在 Python 中实现大写字母的加密技术。我们将只加密文本中的大写字符,其余字符保持不变。
我们先来看看加密大写字母的分步过程:

  1. 定义移位值,即我们要从每个字符移位的位置数。
  2. 遍历纯文本的每个字符:
    1. 如果字符是大写的:
      1. 计算字符在 0-25 范围内的位置/索引。
      2.  使用模运算执行 正移。
      3. 在新位置找到角色。
      4. 用这个新字符替换当前的大写字母。
    2. 否则,如果字符不是大写,则保持不变。

现在让我们看一下代码:

shift = 3 # defining the shift count

text = "HELLO WORLD"

encryption = ""

for c in text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the shift
        new_index = (c_index + shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to encrypted string
        encryption = encryption + new_character

    else:

        # since character is not uppercase, leave it as it is
        encryption += c
        
print("Plain text:",text)

print("Encrypted text:",encryption)

输出:

正如我们所看到的,“HELLO WORLD”的加密文本是“KHOOR ZRUOG”,它与我们在介绍部分手动获得的文本相匹配。
此外,此方法不加密空格字符,它在加密版本中仍然是一个空格。

大写字母解密

现在我们已经知道使用 Ceaser Cipher 对纯文本大写字母进行加密,让我们看看如何将密文解密为纯文本。

早些时候,我们研究了加密过程的数学公式。现在让我们检查一下解密过程。

x = (c - n) % 26

符号的含义与前面的公式相同。
如果任何值在减法后变为负数,模运算符将处理它,并将它环绕起来。

让我们看一下解密过程的逐步实现,这或多或少是加密的逆过程:

  • 定义班次数
  • 遍历加密文本中的每个字符:
    • 如果字符是大写字母:
      1. 计算字符在 0-25 范围内的位置/索引。
      2.  使用模运算执行 负移位。
      3. 在新位置找到角色。
      4. 用这个新字符(也将是大写字母)替换当前的加密字母。
      5. 否则,如果字符不是大写,则保持不变。

让我们为上面的过程编写代码:

shift = 3 # defining the shift count

encrypted_text = "KHOOR ZRUOG"

plain_text = ""

for c in encrypted_text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the negative shift
        new_index = (c_index - shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to plain string
        plain_text = plain_text + new_character

    else:

        # since character is not uppercase, leave it as it is
        plain_text += c

print("Encrypted text:",encrypted_text)

print("Decrypted text:",plain_text)

输出:

请注意我们是如何从加密形式中成功恢复原始文本“HELLO WORLD”的。

加密数字和标点符号

现在我们已经了解了如何使用凯撒密码对英文字母的大写字母进行编码和解码,这引出了一个重要的问题——其他字符呢?
数字呢?特殊字符和标点符号呢?

好吧,最初的凯撒密码算法不应该处理除字母表中的 26 个字母之外的任何东西——无论是大写还是小写。
因此,典型的凯撒密码不会加密标点符号或数字,而是会将所有字母转换为小写或大写,并仅对这些字符进行编码。

但我们始终可以扩展现有的良好解决方案并对其进行调整以适应我们的需求——这适用于软件工程中的任何类型的挑战。
因此,我们将尝试按照上一节中的方式对大写和小写字符进行编码,我们暂时忽略标点符号,然后我们还将对文本中的数字进行编码。

对于数字,我们可以通过以下两种方式之一进行加密:

  1. 将数字值移动与移动字母表中的字母相同的量,即移动 3 – 数字 5 变为 8,2 变为 5,9 变为 2,依此类推。
  2. 使数字成为字母表的一部分,即 z 或 Z 后跟 0,1,2。最多 9,这次我们的模运算除数将是 36 而不是 26。

我们将使用第一种策略实施我们的解决方案。此外,这一次,我们将把我们的解决方案实现为一个接受移位值(作为凯撒密码中的密钥)作为参数的函数。
我们将实现 2 个函数 ——cipher_encrypt() 和 cipher_decrypt()
让我们开始动手吧!

解决方案

# The Encryption Function
def cipher_encrypt(plain_text, key):

    encrypted = ""

    for c in plain_text:

        if c.isupper(): #check if it's an uppercase character

            c_index = ord(c) - ord('A')

            # shift the current character by key positions
            c_shifted = (c_index + key) % 26 + ord('A')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.islower(): #check if its a lowecase character

            # subtract the unicode of 'a' to get index in [0-25) range
            c_index = ord(c) - ord('a') 

            c_shifted = (c_index + key) % 26 + ord('a')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_new = (int(c) + key) % 10

            encrypted += str(c_new)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            encrypted += c

    return encrypted

# The Decryption Function
def cipher_decrypt(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.isupper(): 

            c_index = ord(c) - ord('A')

            # shift the current character to left by key positions to get its original position
            c_og_pos = (c_index - key) % 26 + ord('A')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_og = (int(c) - key) % 10

            decrypted += str(c_og)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            decrypted += c

    return decrypted

现在我们已经定义了两个函数,让我们首先使用加密函数来加密朋友通过短信分享给他的好友的秘密消息。

plain_text = "Mate, the adventure ride in Canberra was so much fun, We were so drunk we ended up calling 911!"

ciphertext = cipher_encrypt(plain_text, 4)

print("Plain text message:\n", plain_text)

print("Encrypted ciphertext:\n", ciphertext)

输出:

请注意除标点符号和空格外的所有内容都是如何加密的。

现在让我们看看尼克弗瑞上校在他的寻呼机上发送的密文:' Sr xli gsyrx sj 7, 6, 5 – Ezirkivw Ewwiqfpi!
原来这是凯撒的密文,幸运的是,我们拿到了这个密文的钥匙!
让我们看看是否可以挖掘出隐藏的信息。

ciphertext = "Sr xli gsyrx sj 7, 6, 5 - Ezirkivw Ewwiqfpi!"

decrypted_msg = cipher_decrypt(ciphertext, 4)

print("The cipher text:\n", ciphertext)

print("The decrypted message is:\n",decrypted_msg)

输出:

一路走好,复仇者联盟!

使用查找表

至此,我们已经了解了凯撒密码的加解密过程,并在Python中实现了相同的过程。

现在我们将看看如何使它更高效、更灵活。具体来说,我们将重点关注如何通过提前构建查找表 
来避免在加密和解密过程中重复计算文本中每个字母的移位位置 。

我们还将研究如何在加密过程中容纳任何一组用户定义的符号,而不仅仅是字母表中的字母。
我们还将加密和解密过程合并到一个函数中,并将接受用户想要执行的两个过程中的哪一个作为参数。

什么是查找表?

查找表只是原始字符和它们应该以加密形式转换成的字符的映射。
到目前为止,我们一直在遍历字符串中的每个字母并计算它们的移位位置。
这是低效的,因为我们的字符集是有限的,而且大多数字符在字符串中出现不止一次。
因此,每次出现它们时计算它们的加密等效值是不高效的,而且如果我们加密包含数十万个字符的非常长的文本,成本会变得很高。

我们可以通过在开始加密过程之前只计算字符集中每个字符的移位位置一次来避免这种情况。
所以如果有 26 个大写字母和 26 个小写字母,我们只需要 52 次计算一次和一些内存空间来存储这个映射。
然后在加密和解密过程中,我们所要做的就是在这个表中执行一次“查找”——一个比每次执行模运算更快的操作。

创建查找表

Python 的 字符串 模块提供了一种简单的方法,不仅可以创建查找表,还可以根据该表翻译任何新字符串。

让我们举一个例子,我们要创建一个包含前五个小写字母及其在字母表中的索引的表。
然后我们使用这个表来翻译一个字符串,其中每个出现的 'a'、'b'、'c'、'd' 和 'e' 都被替换为 '0'、'1'、'2' , '3' 和 '4' 分别; 其余字符保持不变。

我们将使用 str模块的maketrans() 函数  来创建表。此方法接受一个需要翻译的字符串作为其第一个参数,另一个相同长度的字符串参数包含第一个字符串中每个字符的映射字符。
 

让我们为一个简单的例子创建一个表。

table = str.maketrans("abcde", "01234")

该表是一个 Python 字典,它将字符的 Unicode 值作为键,并将它们对应的映射作为值。
现在我们已经准备好表格,我们可以使用该表格翻译任意长度的字符串。
幸运的是,翻译也由 str 模块中的另一个函数处理,称为 translate。

让我们使用此方法使用我们的表格转换我们的文本。

text = "Albert Einstein, born in Germany, was a prominent theoretical physicist."

translated = text.translate(table)

print("Original text:/n", text)

print("Translated text:/n", translated)

输出:

如您所见,前五个小写字母的每个实例都已替换为它们的相对索引。

我们现在将使用相同的技术根据提供的密钥为 Caesar Cipher 创建一个查找表。

实施加密

让我们创建一个函数 caesar_cipher()  ,它接受要加密/解密的字符串、显示字符串中哪些字符应该加密的“字符集”(这将默认为小写字母)、密钥和显示是否解密的布尔
值已执行或以其他方式(加密)。

import string

def cipher_cipher_using_lookup(text,  key, characters = string.ascii_lowercase, decrypt=False):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    table = str.maketrans(characters, characters[key:]+characters[:key])
    
    translated_text = text.translate(table)
    
    return translated_text

现在这是一个强大的功能!

整个移位操作已经简化为切片操作
此外,我们正在使用 string.ascii_lowercase 属性——它是一个从“a”到“z”的字符串。
我们在这里实现的另一个重要特性是同一个函数实现了加密和解密;这可以通过更改“key”参数的值来完成。
切片操作连同这个新密钥确保字符集已左移——我们在解密右移凯撒密文时所做的事情。

让我们使用之前的示例来验证这是否有效。
我们将只加密文本的大写字母,并将相同的内容提供给“字符”参数。
我们将加密文本:“HELLO WORLD!欢迎来到密码学世界!”

text = "HELLO WORLD! Welcome to the world of Cryptography!"

encrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=False)

print(encrypted)

输出:

在我们的第一个示例中,检查“KHOOR ZRUOG”部分如何与使用密钥 3 加密的“HELLO WORLD”相匹配。另外,请注意我们使用string.ascii_uppercase
将字符集指定为大写字母 

我们可以使用我们在之前的结果中获得的相同加密文本来检查解密是否正常工作。
如果我们可以恢复原始文本,则意味着我们的功能可以完美运行。

text = "KHOOR ZRUOG! Zelcome to the world of Fryptography!"

decrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=True)

print(decrypted)

输出:

 请注意我们如何将函数中的“ decrypt”参数设置为 True。
由于我们已经恢复了原始文本,这表明我们使用查找表的加密解密算法运行良好!

现在让我们看看是否可以 扩展字符集, 使其不仅包括小写/大写字符,还包括数字和标点符号。

character_set = string.ascii_lowercase + string.ascii_uppercase + string.digits + " "+ string.punctuation

print("Extended character set:\n", character_set)

plain_text = "My name is Dave Adams. I am living on the 99th street. Please send the supplies!"

encrypted = cipher_cipher_using_lookup(plain_text, 5, character_set, decrypt=False)

print("Plain text:\n", plain_text)

print("Encrypted text:\n", encrypted)

输出:

在这里,我们将到目前为止讨论的所有字符(包括空格字符)都包含在要编码的字符集中。
结果,纯文本中的所有内容(甚至空格)都被另一个符号替换了!
这里唯一的区别是环绕不会针对小写或大写字符单独发生,而是作为一个整体针对整个字符集发生。
这意味着移位 3 的“Y”不会变成“B”,而是会被编码为“1”。

负偏移

到目前为止,我们一直在对加密过程中的字符进行“正”移位或“右移位”。并且相同的解密过程涉及对字符进行“负”移位或“左移位”。
但是,如果我们想执行带有负偏移的加密过程怎么办?我们的加密解密算法会改变吗?
是的,它会,但只是轻微的。左移我们唯一需要做的改变就是让密钥的符号为负,其余过程保持不变,将达到加密过程左移,解密过程右移的结果。

 让我们通过向我们的函数 cipher_cipher_using_lookup()添加一个参数 –  'shift_type'来修改我们之前的函数来尝试这一点。

import string

def cipher_cipher_using_lookup(text, key, characters = string.ascii_lowercase, decrypt=False, shift_type="right"):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    if shift_type=="left":

        # if left shift is desired, we simply inverse they sign of the key
        key = -key

    table = str.maketrans(characters, characters[key:]+characters[:key])

    translated_text = text.translate(table)

    return translated_text

让我们在一个简单的文本上测试这个修改后的方法。

text = "Hello World !"

encrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = False, shift_type="left")

print("plain text:", text)

print("encrypted text with negative shift:",encrypted)

输出:

注意纯文本中的每个字符是如何向左移动三个位置的。
现在让我们使用相同的字符串检查解密过程。

text = "Ebiil Tloia !"

decrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = True, shift_type="left")

print("encrypted text with negative shift:", text)

print("recovered text:",decrypted)

输出:

所以我们可以使用查找表和否定密钥来加密和解密文本。

文件加密

在本节中,我们将了解如何使用 Caesar Cipher 加密文件。
请注意,我们只能加密纯文本文件,而不能加密二进制文件,因为我们知道纯文本文件的字符集。
因此,您可以使用以下两种方法之一来加密文件:

  1. 将整个文件读入一个字符串,加密该字符串并将其转储到另一个文件中。
  2. 一次一行地迭代读取文件,加密该行,然后将其写入另一个文本文件。

我们采用第二种方法,因为第一种方法仅适用于内容可以轻松装入内存的小文件。
因此,让我们定义一个接受文件并使用右移 3 位的凯撒密码对其进行加密的函数。我们将使用小写字母的默认字符集。

def fileCipher(fileName, outputFileName, key = 3, shift_type = "right", decrypt=False):

    with open(fileName, "r") as f_in:

        with open(outputFileName, "w") as f_out:

            # iterate over each line in input file
            for line in f_in:

                #encrypt/decrypt the line
                lineNew = cipher_cipher_using_lookup(line, key, decrypt=decrypt, shift_type=shift_type)

                #write the new line to output file
                f_out.write(lineNew)
                    
    print("The file {} has been translated successfully and saved to {}".format(fileName, outputFileName))

该函数接受我们在上一节中看到的输入文件名、输出文件名和加密/解密参数。

让我们加密一个文件“ milky_way.txt ”(在维基百科上有“Milky Way”页面的介绍段落)。
我们将加密后的文件输出到‘ milky_way_encrypted.txt ’。

让我们使用上面定义的函数对其进行加密:

inputFile = "./milky_way.txt"

outputFile = "./milky_way_encrypted.txt"

fileCipher(inputFile, outputFile, key=3, shift_type="right", decrypt = False)

输出:

让我们检查一下我们的加密文件“ milky_way_encrypted.txt ”现在的样子:

Tkh Mlonb Wdb lv wkh jdodab wkdw frqwdlqv rxu Srodu Sbvwhp, zlwk wkh qdph ghvfulelqj wkh jdodab'v dsshdudqfh iurp Eduwk: d kdcb edqg ri 
oljkw vhhq lq wkh qljkw vnb iruphg iurp vwduv wkdw fdqqrw eh lqglylgxdoob glvwlqjxlvkhg eb wkh qdnhg hbh.
Tkh whup Mlonb Wdb lv d...
...
...

所以我们的函数正确地加密了文件。
作为练习,您可以通过将加密文件路径作为输入传递并将“解密”参数设置为 True 来尝试解密功能。
看看您是否能够恢复原始文本。

确保您没有传递与输入和输出相同的文件路径,这会导致意外结果,因为程序会同时对同一文件进行读写操作。

多次轮班(Vigenère Cipher)

到目前为止,我们已经使用单个移位值(键)将字符串的所有字符移位相同的编号。职位。
我们也可以尝试这个的变体,我们不会使用一个键,而是使用一系列键在文本的不同位置执行不同的移位。

例如,假设我们使用 4 个键的序列:[1,5,2,3] 使用此方法,文本中的第一个字符将移动一个位置,第二个字符将移动五个位置,
第三个字符移动两个位置,第四个字符移动三个位置,然后第五个字符再次移动一个位置,依此类推。
这是凯撒密码的改进版本,称为 维吉尼亚密码。

让我们来实现 Vigenère 密码。

def vigenere_cipher(text, keys, decrypt=False):

    # vigenere cipher for lowercase letters
    n = len(keys)

    translatedText =""

    i = 0 #used to record the count of lowercase characters processed so far

    # iterate over each character in the text
    for c in text:

        #translate only if c is lowercase
        if c.islower():

            shift = keys[i%n] #decide which key is to be used

            if decrypt == True:

                # if decryption is to be performed, make the key negative
                shift = -shift

            # Perform the shift operation
            shifted_c = chr((ord(c) - ord('a') + shift)%26 + ord('a'))

            translatedText += shifted_c

            i += 1

        else:

            translatedText += c
            
    return translatedText

该函数根据布尔参数“decrypt”的值执行加密和解密。
我们保持使用变量 i 编码/解码的小写字母总数,我们将其与模运算符一起使用以确定下一个要使用的列表中的哪个键。
请注意,我们已经使移位操作非常紧凑;这相当于我们之前看到的在 Unicode 和字符值之间转换以及计算移位的多步骤过程。

让我们使用另一个纯文本来测试这个函数:

text = "we will call the first manned moon mission the Project Apollo"

encrypted_text = vigenere_cipher(text, [1,2,3])

print("Plain text:\n", text)

print("Encrypted text:\n", encrypted_text)

输出:

在这里,我们使用密钥 [1,2,3]执行加密 ,正如预期的那样,第一个字符“w”已移动一个位置为“x”,
第二个字符“e”已移动两个位置为'G'; 第三个字符“w”移动了三个位置到“z”。
对后续字符重复此过程。
继续使用相同的密钥执行解密过程,看看是否可以恢复原始语句。

为什么凯撒密码很弱?

尽管理解和实施凯撒密码非常简单,但它使任何人都可以更轻松地找出解密方法而无需付出很多努力。
凯撒密码是一种替换密码技术,我们用一些固定字符替换文本中的每个字符。

如果有人识别出密文中某些字符出现的规律和模式,他们将很快识别出已使用凯撒密码对文本进行加密。
一旦您确信凯撒密码技术已用于加密文本,那么在没有密钥的情况下恢复原始文本就是小菜一碟。
一个简单的 BruteForce 算法在有限的时间内找出原始文本。

蛮力攻击

破解使用凯撒密码编码的密文只是尝试所有可能的密钥。
这是可行的,因为可以生成唯一密文的密钥数量有限。

例如,如果密文对所有小写文本进行了编码,我们所要做的就是使用 0 到 25 的密钥值运行解密步骤。
即使用户提供的密钥大于 25,它也会生成一个密文,即与使用 0 到 25 之间的密钥生成的那些相同。

让我们检查一个所有小写字符都已编码的密文,看看我们是否可以使用 BruteForce 攻击从中提取合理的文本。
我们手头的文字是:

"ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

让我们首先定义接受密文和密钥的解密函数,并解密其所有小写字母。

def cipher_decrypt_lower(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        else:

            decrypted += c

    return decrypted

现在我们有了文本,但我们不知道键,即移位值。让我们编写一个暴力攻击,尝试从 0 到 25 的所有密钥并显示每个解密的字符串:

cryptic_text = "ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

for i in range(0,26):

    plain_text = cipher_decrypt_lower(cryptic_text, i)

    print("For key {}, decrypted text: {}".format(i, plain_text))

输出:

输出列出了您可以从解密中生成的所有字符串。
如果仔细观察,键为 14 的字符串是有效的英语语句,因此是正确的选择。

现在您知道如何破解凯撒密码加密文本了。
我们可以使用凯撒密码的其他更强大的变体,例如使用多次移位(维吉尼亚密码),但即使在这些情况下,坚定的攻击者也可以轻松找出正确的解密方法。
所以凯撒密码算法相对于现代加密算法弱得多。

结论

在本教程中,我们了解了 Caesar Cipher 是什么,如何在 Python 中轻松实现它,以及如何使用我们所谓的“查找表”进一步优化其实现。
我们编写了一个 Python 函数来实现一个通用的 Caesar Cipher 加密/解密算法,该算法将各种用户输入作为参数,而无需做太多假设。

然后,我们研究了如何使用 Caesar Cipher 加密文件,以及如何使用多次轮班来加强 Caesar Cipher。
最后,我们研究了 Caesar Cipher 对 BruteForce 攻击的脆弱性。

文章原文出处:https: //likegeeks.com/

#python #cryptography 

如何在 Python 中使用凯撒密码
Rocio  O'Keefe

Rocio O'Keefe

1680837780

How to Caesar Cipher in Python

Cryptography deals with encrypting or encoding a piece of information (in a plain text) into a form that looks gibberish and makes little sense in ordinary language.
This encoded message(also called ciphertext) can then be decoded back into a plain text by the intended recipient using a decoding technique (often along with a private key) communicated to the end-user.

Caesar Cipher is one of the oldest encryption technique that we will focus on in this tutorial, and will implement the same in Python.
Although Caesar Cipher is a very weak encryption technique and is rarely used today, we are doing this tutorial to introduce our readers, especially the newcomers, to encryption.
Consider this as the ‘Hello World’ of Cryptography.

What is Caesar Cipher?

Caesar Cipher is a type of substitution cipher, in which each letter in the plain text is replaced by another letter at some fixed positions from the current letter in the alphabet.

For example, if we shift each letter by three positions to the right, each of the letters in our plain text will be replaced by a letter at three positions to the right of the letter in the plain text.
Let us see this in action – let’s encrypt the text “HELLO WORLD” using a right shift of 3.

So the letter H will be replaced by K, E will be replaced by H, and so on. The final encrypted message for HELLO WORLD will be KHOOR ZRUOG. That gibberish doesn’t make sense, does it?

Note that the letters on edge i.e., X, Y, Z wrap around and are replaced by A, B, C respectively, in case of the right shift. Similarly, the letters in the beginning – A, B, C, etc. will be wrapped around in case of left shifts.

The Caesar Cipher encryption rule can be expressed mathematically as:

c = (x + n) % 26

Where c is the encoded character, x is the actual character, and n is the number of positions we want to shift the character x by. We’re taking mod with 26 because there are 26 letters in the English alphabet.

Caesar Cipher in Python

Before we dive into defining the functions for the encryption and decryption process of Caesar Cipher in Python, we’ll first look at two important functions that we’ll use extensively during the process – chr() and ord().
It is important to realize that the alphabet as we know them, is stored differently in a computer’s memory. The computer doesn’t understand any of our English language’s alphabet or other characters by itself.

Each of these characters is represented in computer memory using a number called ASCII code (or its extension – the Unicode) of the character, which is an 8-bit number and encodes almost all the English language’s characters, digits, and punctuations.
For instance, the uppercase ‘A’ is represented by the number 65, ‘B’ by 66, and so on. Similarly, lowercase characters’ representation begins with the number 97.

As the need to incorporate more symbols and characters of other languages arose, the 8 bit was not sufficient, so a new standard – Unicode – was adopted, which represents all the characters used in the world using 16 bits.
ASCII is a subset of Unicode, so the ASCII encoding of characters remains the same in Unicode. That means ‘A’ will still be represented using the number 65 in Unicode.
Note that the special characters like space ” “, tabs “\t”, newlines “\n”, etc. are also represented in memory by their Unicode.

We’ll look at two built-in functions in Python that are used to find the Unicode representation of a character and vice-versa.

The ord() function

You can use the ord() method to convert a character to its numeric representation in Unicode. It accepts a single character and returns the number representing its Unicode. Let’s look at an example.

c_unicode = ord("c")

A_unicode = ord("A")

print("Unicode of 'c' =", c_unicode)

print("Unicode of 'A' =", A_unicode)

Output:

The chr() function

Just like how we could convert a character into its numeric Unicode using ord() method, we do the inverse i.e., find the character represented by a number using chr() method.
The chr() method accepts a number representing the Unicode of a character and returns the actual character corresponding to the numeric code.
Let’s first look at a few examples:

character_65 = chr(65)

character_100 = chr(100)

print("Unicode 65 represents", character_65)

print("Unicode 100 represents", character_100)

character_360 = chr(360)

print("Unicode 360 represents", character_360)

Output:

Notice how the German letter Ü (U umlaut) is also represented in Unicode by the number 360.

We can also apply a chained operation(ord followed by chr) to get the original character back.

c = chr(ord("Ũ"))

print(c)

Output: Ũ

Encryption for Capital Letters

Now that we understand the two fundamental methods we’ll use, let’s implement the encryption technique for capital letters in Python. We shall encrypt only the uppercase characters in the text and will leave the remaining ones unchanged.
Let’s first look at the step-by-step process of encrypting the capital letters:

  1. Define the shift value i.e., the number of positions we want to shift from each character.
  2. Iterate over each character of the plain text:
    1. If the character is upper-case:
      1. Calculate the position/index of the character in the 0-25 range.
      2. Perform the positive shift using the modulo operation.
      3. Find the character at the new position.
      4. Replace the current capital letter by this new character.
    2. Else, If the character is not upper-case, keep it with no change.

Let us now look at the code:

shift = 3 # defining the shift count

text = "HELLO WORLD"

encryption = ""

for c in text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the shift
        new_index = (c_index + shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to encrypted string
        encryption = encryption + new_character

    else:

        # since character is not uppercase, leave it as it is
        encryption += c
        
print("Plain text:",text)

print("Encrypted text:",encryption)

Output:

As we can see, the encrypted text for “HELLO WORLD” is “KHOOR ZRUOG”, and it matches the one we arrived at manually in the Introduction section.
Also, this method doesn’t encrypt the space character, and it continues to be a space in the encrypted version.

Decryption for Capital Letters

Now that we’ve figured out the encryption for plain text capital letters using Ceaser Cipher let’s look at how we will decrypt the ciphertext into plain text.

Earlier, we looked at the mathematic formulation of the encryption process. Let’s now check out the same for the decryption process.

x = (c - n) % 26

The meaning of the notations remains the same as in the previous formula.
If any value becomes negative after subtraction, the modulo operator will take care of that, and it will wrap it around.

Let us look at the step-by-step implementation of the decryption process, which will be more or less the reverse of the encryption:

  • Define the number of shifts
  • Iterate over each character in the encrypted text:
    • If the character is an uppercase letter:
      1. Calculate the position/index of the character in the 0-25 range.
      2. Perform the negative shift using the modulo operation.
      3. Find the character at the new position.
      4. Replace the current encrypted letter by this new character (which will also be an uppercase letter).
      5. Else, if the character is not capital, keep it unchanged.

Let’s write the code for the above procedure:

shift = 3 # defining the shift count

encrypted_text = "KHOOR ZRUOG"

plain_text = ""

for c in encrypted_text:

    # check if character is an uppercase letter
    if c.isupper():

        # find the position in 0-25
        c_unicode = ord(c)

        c_index = ord(c) - ord("A")

        # perform the negative shift
        new_index = (c_index - shift) % 26

        # convert to new character
        new_unicode = new_index + ord("A")

        new_character = chr(new_unicode)

        # append to plain string
        plain_text = plain_text + new_character

    else:

        # since character is not uppercase, leave it as it is
        plain_text += c

print("Encrypted text:",encrypted_text)

print("Decrypted text:",plain_text)

Output:

Notice how we have successfully recovered the original text “HELLO WORLD” from its encrypted form.

Encrypting numbers and punctuation

Now that we’ve seen how we can encode and decode capital letters of the English alphabet using Caesar Cipher, it begs an important question – What about the other characters?
What about the numbers? What about the special characters and the punctuation?

Well, the original Caesar Cipher algorithm was not supposed to deal with anything other than the 26 letters of the alphabet – either in uppercase or lowercase.
So a typical Caesar Cipher would not encrypt punctuation or numbers and would convert all the letters to either lowercase or uppercase and encode only those characters.

But we can always extend an existing good solution and tweak them to suit our needs – that’s true for any kind of challenge in software engineering.
So we’ll try to encode uppercase and lowercase characters the way we did in the previous section, we’ll ignore the punctuations for now, and then we’ll also encode the numbers in the text.

For numbers, we can do the encryption in one of the two ways:

  1. Shift the digit value by the same amount as you shift the letters of the alphabet, i.e., for a shift of 3 – digit 5 becomes 8, 2 becomes 5, 9 becomes 2, and so on.
  2. Make the numbers part of the alphabet, i.e., z or Z will be followed by 0,1,2. up to 9, and this time our divider for modulo operation will be 36 instead of 26.

We’ll implement our solution using the first strategy. Also, this time, we’ll implement our solution as a function that accepts the shift value (which serves as the key in Caesar Cipher) as a parameter.
We’ll implement 2 functions – cipher_encrypt() and cipher_decrypt()
Let’s get our hands dirty!

The solution

# The Encryption Function
def cipher_encrypt(plain_text, key):

    encrypted = ""

    for c in plain_text:

        if c.isupper(): #check if it's an uppercase character

            c_index = ord(c) - ord('A')

            # shift the current character by key positions
            c_shifted = (c_index + key) % 26 + ord('A')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.islower(): #check if its a lowecase character

            # subtract the unicode of 'a' to get index in [0-25) range
            c_index = ord(c) - ord('a') 

            c_shifted = (c_index + key) % 26 + ord('a')

            c_new = chr(c_shifted)

            encrypted += c_new

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_new = (int(c) + key) % 10

            encrypted += str(c_new)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            encrypted += c

    return encrypted

# The Decryption Function
def cipher_decrypt(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.isupper(): 

            c_index = ord(c) - ord('A')

            # shift the current character to left by key positions to get its original position
            c_og_pos = (c_index - key) % 26 + ord('A')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        elif c.isdigit():

            # if it's a number,shift its actual value 
            c_og = (int(c) - key) % 10

            decrypted += str(c_og)

        else:

            # if its neither alphabetical nor a number, just leave it like that
            decrypted += c

    return decrypted

Now that we’ve defined our two functions let’s first use the encryption function to encrypt a secret message a friend is sharing via text message to his buddy.

plain_text = "Mate, the adventure ride in Canberra was so much fun, We were so drunk we ended up calling 911!"

ciphertext = cipher_encrypt(plain_text, 4)

print("Plain text message:\n", plain_text)

print("Encrypted ciphertext:\n", ciphertext)

Output:

Notice how everything except punctuation and spaces has been encrypted.

Now let us look at a ciphertext that Colonel Nick Fury was sending on his pager: ‘Sr xli gsyrx sj 7, 6, 5 – Ezirkivw Ewwiqfpi!
It turns out it’s Caesar’s ciphertext and fortunately, we got our hands on the key to this ciphertext!
Let’s see if we can unearth the hidden message.

ciphertext = "Sr xli gsyrx sj 7, 6, 5 - Ezirkivw Ewwiqfpi!"

decrypted_msg = cipher_decrypt(ciphertext, 4)

print("The cipher text:\n", ciphertext)

print("The decrypted message is:\n",decrypted_msg)

Output:

Way to go, Avengers!

Using a lookup table

At this stage, we have understood the encryption and decryption process of the Caesar Cipher, and have implemented the same in Python.

Now we will look at how it can be made more efficient and more flexible.
Specifically, we’ll focus on how we can avoid the repeated computations of the shifted positions for each letter in the text during the encryption and decryption process, by building a lookup table ahead of time.

We’ll also look at how we can accommodate any set of user-defined symbols and not just the letters of the alphabet in our encryption process.
We’ll also merge the encryption and decryption process into one function and will accept as a parameter which of the two processes the user wants to execute.

What is a lookup table?

A lookup table is simply a mapping of the original characters and the characters they should translate to in an encrypted form.
So far, we have been iterating over each of the letters in the string and computing their shifted positions.
This is inefficient because our character set is limited, and most of them occur more than once in the string.
So computing their encrypted equivalence each time they occur is not efficient, and it becomes costly if we are encrypting a very long text with hundreds of thousands of characters in it.

We can avoid this by computing the shifted positions of each of the characters in our character set only once before starting the encryption process.
So if there are 26 uppercase and 26 lowercase letters, we’d need only 52 computations once and some space in memory to store this mapping.
Then during the encryption and decryption process, all we’d have to do is perform a ‘lookup’ in this table – an operation that is faster than performing a modulo operation each time.

Creating a lookup table

Python’s string module provides an easy way not just to create a lookup table, but also to translate any new string based on this table.

Let’s take an example where we want to create a table of the first five lowercase letters and their indices in the alphabet.
We’d then use this table to translate a string where each of the occurrences of ‘a’, ‘b’, ‘c’, ‘d’ and ‘e’ are replaced by ‘0’, ‘1’, ‘2’, ‘3’ and ‘4’ respectively; and the remaining characters are untouched.

We will use the maketrans() function of the str module to create the table.
This method accepts as its first parameter, a string of characters for which translation is needed, and another string parameter of the same length that contains the mapped characters for each character in the first string.

Let’s create a table for a simple example.

table = str.maketrans("abcde", "01234")

The table is a Python dictionary that has the characters’ Unicode values as keys, and their corresponding mappings as values.
Now that we have our table ready, we can translate strings of any length using this table.
Fortunately, the translation is also handled by another function in the str module, called translate.

Let’s use this method to convert our text using our table.

text = "Albert Einstein, born in Germany, was a prominent theoretical physicist."

translated = text.translate(table)

print("Original text:/n", text)

print("Translated text:/n", translated)

Output:

As you can see, each instance of the first five lowercase letters have been replaced by their relative indices.

We’ll now use the same technique to create a lookup table for Caesar Cipher, based on the key provided.

Implementing the encryption

Let’s create a function caesar_cipher() that accepts a string to be encrypted/decrypted, the ‘character set’ showing which characters in the string should be encrypted (this will default to lowercase letters),
the key, and a boolean value showing if decryption has performed or otherwise(encryption).

import string

def cipher_cipher_using_lookup(text,  key, characters = string.ascii_lowercase, decrypt=False):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    table = str.maketrans(characters, characters[key:]+characters[:key])
    
    translated_text = text.translate(table)
    
    return translated_text

Now that’s one powerful function out there!

The whole shifting operation has been reduced to a slicing operation.
Also, we are using string.ascii_lowercase attribute – it is a string of characters from ‘a’ to ‘z’.
Another important feature we’ve achieved here is that the same function achieves both encryption and decryption; this can be done by changing the value of the ‘key’ parameter.
The slicing operation along with this new key ensures the character set has been left-shifted – something we do in the decryption of a right shift Caesar ciphertext.

Let’s validate if this works by using an earlier example.
We’ll encrypt only capital letters of the text and will supply the same to the ‘characters’ parameter.
We’ll encrypt the text: “HELLO WORLD! Welcome to the world of Cryptography!”

text = "HELLO WORLD! Welcome to the world of Cryptography!"

encrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=False)

print(encrypted)

Output:

Check how the “KHOOR ZRUOG” part matches to encryption of “HELLO WORLD” with key 3 in our first example.
Also, note that we are specifying the character set to be uppercase letters using string.ascii_uppercase

We can check if decryption works properly by using the same encrypted text we got in our previous result.
If we can recover our original text back, that means our function works perfectly.

text = "KHOOR ZRUOG! Zelcome to the world of Fryptography!"

decrypted = cipher_cipher_using_lookup(text, 3, string.ascii_uppercase, decrypt=True)

print(decrypted)

Output:

Notice how we have set the ‘decrypt’ parameter in our function to True.
Since we have recovered our original text back, it’s a sign our encryption-decryption algorithm using a lookup table is works well!

Let’s now see if we can extend the character set to include not just lowercase/uppercase characters but also digits and punctuations.

character_set = string.ascii_lowercase + string.ascii_uppercase + string.digits + " "+ string.punctuation

print("Extended character set:\n", character_set)

plain_text = "My name is Dave Adams. I am living on the 99th street. Please send the supplies!"

encrypted = cipher_cipher_using_lookup(plain_text, 5, character_set, decrypt=False)

print("Plain text:\n", plain_text)

print("Encrypted text:\n", encrypted)

Output:

Here we included all the characters we discussed so far (including space character) in the character set to be encoded.
As a result, everything (even the spaces) in our plain text has been replaced by another symbol!
The only difference here is that the wrap-around doesn’t happen individually for lowercase or uppercase characters, but it happens as a whole for the entire character set.
That means ‘Y’ with a shift of 3 will not become ‘B’, but will be encoded to ‘1’.

Negative shift

So far we’ve been doing ‘positive’ shifts or ‘right shifts’ of the characters in the encryption process. And the decryption process for the same involved doing a ‘negative’ shift or ‘left shift’ of the characters.
But what if we want to perform the encryption process with a negative shift? Would our encryption-decryption algorithm change?
Yes, it will, but only slightly. The only change we need for a left shift is to make the sign of the key negative, the rest of the process shall remain the same and will achieve the result of a left shift in encryption and a right shift in the decryption process.

Let us try this by modifying our previous function by adding one more parameter – ‘shift_type’ to our function cipher_cipher_using_lookup().

import string

def cipher_cipher_using_lookup(text, key, characters = string.ascii_lowercase, decrypt=False, shift_type="right"):

    if key < 0:

        print("key cannot be negative")

        return None

    n = len(characters)

    if decrypt==True:

        key = n - key

    if shift_type=="left":

        # if left shift is desired, we simply inverse they sign of the key
        key = -key

    table = str.maketrans(characters, characters[key:]+characters[:key])

    translated_text = text.translate(table)

    return translated_text

Let us test this modified method on a simple text.

text = "Hello World !"

encrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = False, shift_type="left")

print("plain text:", text)

print("encrypted text with negative shift:",encrypted)

Output:

Notice how each of the characters in our plain text has been shifted to the left by three positions.
Let’s now check the decryption process using the same string.

text = "Ebiil Tloia !"

decrypted = cipher_cipher_using_lookup(text, 3, characters = (string.ascii_lowercase + string.ascii_uppercase), decrypt = True, shift_type="left")

print("encrypted text with negative shift:", text)

print("recovered text:",decrypted)

Output:

So we could encrypt and decrypt a text using a lookup table and a negative key.

File encryption

In this section, we’ll look at using Caesar Cipher to encrypt a file.
Note that we can only encrypt plain text files, and not binary files because we know the character set for plain text files.
So, you can encrypt a file using one of the following two approaches:

  1. Read the whole file into a string, encrypt the string and dump it into another file.
  2. Iteratively read the file one line at a time, encrypt the line, and write it to another text file.

We’ll go with the second approach because the first one is feasible only for small files whose content can fit into memory easily.
So let’s define a function that accepts a file and encrypts it using Caesar Cipher with a right shift of 3. We’ll use the default character set of lower case letters.

def fileCipher(fileName, outputFileName, key = 3, shift_type = "right", decrypt=False):

    with open(fileName, "r") as f_in:

        with open(outputFileName, "w") as f_out:

            # iterate over each line in input file
            for line in f_in:

                #encrypt/decrypt the line
                lineNew = cipher_cipher_using_lookup(line, key, decrypt=decrypt, shift_type=shift_type)

                #write the new line to output file
                f_out.write(lineNew)
                    
    print("The file {} has been translated successfully and saved to {}".format(fileName, outputFileName))

The function accepts the input file name, output file name, and the encryption/decryption parameters we saw in the last section.

Let’s encrypt a file ‘milky_way.txt‘ (has the introductory paragraph of the ‘Milky Way’ page on Wikipedia).
We will output the encrypted file to ‘milky_way_encrypted.txt‘.

Let’s encrypt it using the function we defined above:

inputFile = "./milky_way.txt"

outputFile = "./milky_way_encrypted.txt"

fileCipher(inputFile, outputFile, key=3, shift_type="right", decrypt = False)

Output:

Let’s check how our encrypted file ‘milky_way_encrypted.txt‘ looks like now:

Tkh Mlonb Wdb lv wkh jdodab wkdw frqwdlqv rxu Srodu Sbvwhp, zlwk wkh qdph ghvfulelqj wkh jdodab'v dsshdudqfh iurp Eduwk: d kdcb edqg ri 
oljkw vhhq lq wkh qljkw vnb iruphg iurp vwduv wkdw fdqqrw eh lqglylgxdoob glvwlqjxlvkhg eb wkh qdnhg hbh.
Tkh whup Mlonb Wdb lv d...
...
...

So our function correctly encrypts the file.
As an exercise, you can try the decryption functionality by passing the encrypted file path as an input and setting the ‘decrypt’ parameter to True.
See if you’re able to recover the original text.

Make sure you don’t pass the same file path as both input and output, which would lead to undesired results as the program would do read and write operation on the same file simultaneously.

Multiple shifts (Vigenère Cipher)

So far, we’ve used a single shift value (key) to shift all the characters of the strings by the same no. of positions.
We can also try a variant of this, where we will not use one key, but a sequence of keys to perform different shifts at different positions in the text.

For instance, let us say we use a sequence of 4 keys: [1,5,2,3] With this method, our 1st character in the text will be shifted by a one position, the second character will be shifted by five positions,
the 3rd character by two positions, the 4th character by three positions, and then again the 5th character will be shifted by one position, and so on.
This is an improved version of Caesar Cipher and is called the Vigenère Cipher.

Let us implement the Vigenère Cipher.

def vigenere_cipher(text, keys, decrypt=False):

    # vigenere cipher for lowercase letters
    n = len(keys)

    translatedText =""

    i = 0 #used to record the count of lowercase characters processed so far

    # iterate over each character in the text
    for c in text:

        #translate only if c is lowercase
        if c.islower():

            shift = keys[i%n] #decide which key is to be used

            if decrypt == True:

                # if decryption is to be performed, make the key negative
                shift = -shift

            # Perform the shift operation
            shifted_c = chr((ord(c) - ord('a') + shift)%26 + ord('a'))

            translatedText += shifted_c

            i += 1

        else:

            translatedText += c
            
    return translatedText

The function performs both encryption and decryption, depending on the value of the boolean parameter ‘decrypt’.
We are keeping the count of the total lowercase letters encoded/decoded using the variable i, we use this with modulo operator to determine which key from the list to be used next.
Notice that we have made the shift operation very compact; this is equivalent to the multi-step process of converting between Unicode and character values and computation of the shift we had seen earlier.

Let us test this function using another plain text:

text = "we will call the first manned moon mission the Project Apollo"

encrypted_text = vigenere_cipher(text, [1,2,3])

print("Plain text:\n", text)

print("Encrypted text:\n", encrypted_text)

Output:

Here we are performing the encryption using the keys [1,2,3] and as expected, the first character ‘w’ has been shifted by one position to ‘x’,
the second character ‘e’ has been shifted by two positions to ‘g’; the third character ‘w’ is shifted by three positions to ‘z’.
This process repeats with subsequent characters.
Go ahead and perform the decryption process with the same keys and see if you can recover the original statement back.

Why Caesar Cipher is weak?

As simple as it is to understand and implement the Caesar Cipher, it makes it easier for anybody to figure out the decryption without a lot of effort.
Caesar Cipher is a substitution cipher technique where we replace each character in the text by some fixed character.

If someone identifies the regularity and pattern in the occurrence of certain characters in a ciphertext, they would quickly identify that Caesar Cipher has been used to encrypt the text.
Once you’re convinced that Caesar Cipher technique has been used to encrypt a text, then recovering the original text without the possession of the key is a cakewalk.
A simple BruteForce algorithm figures out the original text in a limited amount of time.

BruteForce Attack

Breaking a ciphertext encoded using Caesar Cipher is only about trying out all the possible keys.
This is feasible because there can only be a limited number of keys that can generate a unique ciphertext.

For instance, if the ciphertext has all the lowercase text encoded, all we have to do is run the decryption step with key values 0 to 25.
Even if the user had supplied a key greater than 25, it would produce a ciphertext that is the same as one of those generated using keys between 0 to 25.

Let’s check out a ciphertext that has all its lowercase characters encoded, and see if we can extract a sensible text from it using a BruteForce attack.
The text at our hand is:

"ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

Let’s first define the decrypt function that accepts a ciphertext and a key, and decrypts all its lowercase letters.

def cipher_decrypt_lower(ciphertext, key):

    decrypted = ""

    for c in ciphertext:

        if c.islower(): 

            c_index = ord(c) - ord('a') 

            c_og_pos = (c_index - key) % 26 + ord('a')

            c_og = chr(c_og_pos)

            decrypted += c_og

        else:

            decrypted += c

    return decrypted

Now we have our text, but we don’t know the key i.e., the shift value. Let’s write a Brute force attack, that tries all the keys from 0 to 25 and displays each of the decrypted strings:

cryptic_text = "ks gvozz ohhoqy hvsa tfca hvs tfcbh oh bccb cb Tisgrom"

for i in range(0,26):

    plain_text = cipher_decrypt_lower(cryptic_text, i)

    print("For key {}, decrypted text: {}".format(i, plain_text))

Output:

The output lists all the strings you can generate from decryption.
If you look at it closely, the string with key 14 is a valid English statement and hence is the correct choice.

Now you know how to break a Caesar Cipher encrypted text.
We could use other, stronger variants of Caesar Cipher, like using multiple shifts (Vigenère cipher), but even in those cases, determined attackers can figure out the correct decryption easily.
So the Caesar Cipher algorithm is relatively much weaker than the modern encryption algorithms.

Conclusion

In this tutorial, we learned what Caesar Cipher is, how it is easy to implement it in Python, and how its implementation can be further optimized using what we call ‘lookup tables’.
We wrote a Python function to implement a generic Caesar Cipher encryption/decryption algorithm that takes various user inputs as the parameter without assuming much.

We then looked at how we can encrypt a file using Caesar Cipher, and then how Caesar Cipher can be strengthened using multiple shifts.
Finally, we looked at how vulnerable Caesar Cipher to BruteForce attacks.

Original article source at: https://likegeeks.com/

#python #cryptography 

How to Caesar Cipher in Python

Write a Request For Proposal (RFP) that Drives Responses

As a marketer, you have a lot of things on your plate and can’t manage everything on your own. Moreover, some tasks are just not possible or practical to manage manually. At some point, you’re going to need to work with other businesses that offer tools or services to help you do your job more efficiently. That’s where a request for proposal comes in, enabling you to attract prospective vendors who can help you achieve your business goals.

If you’ve never written a request for proposal (RFP) before, you may not know how to get started or what you need to include. The good news is, we’re here to help. This guide walks you through the process of writing a successful request for proposal that drives responses from the most viable vendors. Let’s dive right in.

What is a Request for Proposal (RFP)?

A request for proposal or RFP is a document that provides a list of requirements that vendors need to meet to complete a project. Typically sent out by businesses that need to find the right technology solution or professional service, it serves as an open invitation for vendors to submit their proposals. This enables them to attract potential vendors who can provide them with the tools they need or to whom they can outsource some of their work.

It's crucial to get your request for proposal right because it details all the criteria that vendors must meet in order to win the bid. As such, it enables you to collect proposals from the most relevant vendors, making it easier to decide on the right one for your business. 


8 Steps to Writing a Request for Proposal

So, if a request for proposal is so important, how do you write one? Check out the steps below to start writing your very own request for proposal.

steps to writing a request for proposal

1: Define the project, scope, and budget

Start with a clear definition of what the project is and understand the role that the vendor will play in it. In other words, have a proper idea of what you need from the vendor before you can write your request for proposal. Discuss what you need the vendor to do, how it should be done, and how long it should ideally take to be completed. 

Additionally, you’d also need to talk about how much you’re willing to spend for the service or platform. This provides you with a solid foundation for your RFP as you clearly know what you’re looking for.  


2: Provide an introduction

Now that you have a clear idea of what you’re looking for, it’s time to write an introduction explaining your project and expectations. The introduction should be able to help potential vendors understand the purpose of your RFP and what they need to help you achieve. This would also be a good opportunity to explain if you’re facing any challenges and how the vendor can help you overcome them.

Besides these basics, you may also want to include additional information about your project. This may be details such as when you intend to start the project and how long it will run. The introduction should help potential vendors get a better idea of your needs so they can assess their ability to meet them.


3: Explain the history of your company and project

Next, it’s time to introduce your company to the vendors. Give them a brief history of your company and what you do as well as the project you’re undertaking. Talk about your brand values, history, and other important background information. This information should be able to help vendors understand your market and where your business currently stands. 

Keep in mind that many of the potential vendors may have never heard of your company before. Make it easy for them to make an informed decision by giving them a sense of who you are as a brand. They can then use this information to assess whether they’re the right fit for your needs and whether they’d want to work with you.


4: Describe your requirements

Now comes the most important part where you describe exactly what you need in a vendor. Provide specific details about the services or solutions that you’re looking for to help you achieve your goal. Be sure to include details such as the level of experience you’re looking for (in the case of service solutions). For software solutions, you may also want to include details such as the level of access you need based on your team size.

It’s important to get as specific as possible in this section so potential vendors can know if they’re offering the solution you need. This will help them decide if they should send in a proposal or not, allowing you to instantly filter your options to get proposals from the most suitable prospects.

For example, if you’re looking for a social media marketing agency, you may be in need of an agency that can take care of content planning, production, and scheduling. Additionally, you may even need them to manage your community on your behalf. In this case, an agency that doesn’t offer community management may opt to avoid sending in a bid, so you don’t need to waste your time reviewing their proposal.

Alternatively, let’s say you’re looking for a social media management tool for a team of three. And you want to be able to plan your content, schedule your posts, monitor your comments, and analyze results all in one place. That way, only those vendors who can meet the above requirements will send in a proposal for you to review so you’re instantly filtering your options.


5: Give submission instructions

Vendors who plan on sending in a proposal should know how to respond to your request for proposal. Make sure you’re providing clear instructions on the structure they should follow in their proposal as well as what they need to include. When all the proposals are formatted in a similar way, it becomes easier for you to process the information and evaluate them.

For example, you may require them to include a certain number of headings. Or you may even request them to provide a list of points under each heading. Additionally, you may also ask them to send in samples of their previous work, case studies, and demos to better evaluate their quality of work or platform capabilities. 


6: Include your selection criteria

It’s also important that you include a detailed list of the criteria using which you’ll be evaluating the proposals. This gives vendors an idea of how they’ll be evaluated so they can understand their chances of winning the bid. As such, only the most qualified vendors will respond to your request for proposal, making it easier for you to sort through your options.

Provide details about your priorities, basic requirements, and preferences so vendors know exactly what you’re looking for and how to position their offerings. For example, you may prioritize agencies that specialize in content production beyond their marketing services. The basic requirements could be the ability to plan and execute social media marketing campaigns, while you may prefer agencies that have experience working with companies in a certain industry.


7: Specify the RFP timeline

Additionally, it’s crucial for everyone involved to know your target timeline. When do you expect to receive the responses? When will the selected vendor be announced? Make sure to include these key deadlines so vendors don’t have to keep reaching out to you for updates when you haven’t made your selection.

Besides these, you’d also want to include your project start time and end time. Knowing these timelines will allow vendors to plan their schedules and assess their availability before they choose to respond. This benefits both parties because you don’t want to end up working with a vendor who’d eventually not be able to help you meet the deadline. Also, vendors will be able to understand whether they can fit your project in considering their current workload.

This is particularly important for RFPs that are seeking service solutions. Keep in mind that depending on how detailed your requirements are, you’ll need to adjust your timeline accordingly. If vendors have to provide a highly detailed proposal, they may require more time to plan their response. 


8: Proofread, revise, and go live

Now that you’ve written down all the crucial information, it’s time to proofread your request for proposal. Look for spelling mistakes and grammatical errors as well as complicated sentences that may be difficult to understand. You want to come across as professional and trustworthy while avoiding any chances of miscommunication.

Besides the basics, make sure you’re on the lookout for mistakes that could be detrimental to your project’s timeline. For instance, a typo in your deadline could result in you losing out on potential vendors because they couldn’t meet it or a huge delay in receiving your proposals. Alternatively, a missing 0 in your project budget could mean losing out on potential vendors who declined to bid because the pay was too low.

Make any necessary revisions and give the RFP a once-over to ensure that it’s professional and clear. You’ll then be able to finally go live with your request for proposal.

Best Practices to Write an Effective RFP

In addition to simply following the steps above, there’s a certain way to make sure that your RFP gets the responses it deserves. Follow these best practices to write an effective request for proposal.

best practices to write FRP

  • Keep It Simple and Easy to Understand

To avoid the chances of miscommunication, make sure you use language that’s understandable to your potential vendors. You may want to cut back on the industry jargon and resort to simple English while still keeping it professional. Try to avoid long run-on sentences and instead cut them to shorter, more bite-sized sentences that are easier to process.

  • Make the Most of Headings and Bullet Points

Headings and bullet points make your RFP easier to digest compared to large blocks of text. Make the most of them to break up your request for proposal and make it more scannable.

  • Be as Detailed as Possible

Don’t miss important details that could help potential vendors understand your project and requirements better. Vendors are more likely to respond with the right proposal when they have a clear idea of what you’re looking for and what kind of role they’ll play.


Example of a Request for Proposal

Still not sure what your request for proposal should look like? Let’s take a look at an example of how a typical RFP looks so you can get a better idea.

Request for Proposal: Social Media Services for June’s Vintage
16 December 2022
Issued by: June’s Vintage
Contact Person: June Phillips
j.phillips@junesvintage.com
(445)917-3069

Introduction

June’s Vintage, a retail store that deals in vintage clothing, is accepting proposals to find a reliable agency to manage our social media on our behalf. The purpose is to:

  • Grow our social media community.
  • Engage our audience on an ongoing basis.
  • Maintain a strong brand presence across leading social networks (Instagram, Facebook, and TikTok).

The objective of this request for proposal is to find a social media agency that will provide the best overall value and deliver impressive results. We’re hoping to run a test project for three months after which we may decide on a long-term partnership.

Background

Our vintage business was established in 2007 and has since established a strong customer base throughout Philadelphia. Most of our customers are local fashion enthusiasts roughly between the ages of 25 and 50 and shop in-store. However, as we expand to online shopping channels, there’s an opportunity to extend this reach beyond the local area. This has proved to be challenging as our social media presence is fairly limited and we lack the time and know-how to actively engage our audience on social media. 

Project Overview

We would like to be able to consistently post and engage with audiences across three key social media platforms–Instagram, Facebook, and TikTok. As such, we’re looking for an agency that can help us with the following:

  • Create a solid social media strategy complete with a publishing calendar.
  • Develop fresh content ideas and take care of content creation in accordance with the publishing calendar.
  • Schedule and publish posts on our behalf.
  • Monitor and respond to customer comments.
  • Run a week-long advertising campaign to attract new followers/customers.

Our budget is $2,500 per month with some room for flexibility depending on the level of service that can be provided. Ideally, we would like to employ an agency that has experience working with small retail stores and local businesses.

Submission Guidelines

All proposals must be created using the format below (bulleted lists will be highly appreciated):

  • Executive summary
  • Business background 
  • Highlight your unique selling point
  • Provide relevant experience that makes you qualified for the project
  • Details of proposed deliverables and services
  • Note the social media management tools you will use to complete the necessary tasks
  • Not how content will be shared with us for approval
  • Include your rates
  • References and/or case studies
  • Provide samples of social media content created for previous clients
  • Additional terms and conditions to work with your agency 

Please submit your proposal in .pdf format to j.phillips@junesvintage.com by January 30, 2023.

Evaluation Criteria

June’s Vintage will use the following criteria to evaluate proposals and select the right vendor:

  • Experience providing full-service social media solutions for a minimum of 24 months
  • Responsiveness to the requirements highlighted above
  • Competitiveness of service rates
  • Testimonials from past/current clients
  • Tools and technology used to carry out necessary tasks

Timeline

June’s Vintage expects to complete the RFP and project according to the following timeline:

  • Issuance of request for proposal – December 16, 2022
  • Deadline to submit proposals – January 30, 2023
  • Vendor selection date – February 15, 2023
  • Finalization of contract and other project discussions – February 20, 2023
  • Project start date – March 1, 2023
  • Initial project completion – May 31, 2023

Getting Started with Your First Request for Proposal

Now that you know exactly what a request for proposal looks like and what to include in it, it’s time to write your very own. There are plenty of free templates available online that can help you draft the perfect request for proposal. 

Original article source at: https://influencermarketinghub.com/

#write #request #example 

Write a Request For Proposal (RFP) that Drives Responses
Bongani  Ngema

Bongani Ngema

1670313480

How to Read From one Table and Write To another in BigQuery

Ever thought how to read from a table in GCP BigQuery and perform some aggregation on it and finally writing the output in another table using Beam Pipeline? In this blog we will be going to achieve the same using cloud dataflow as runner.

This blog will perform the task which will gather the month in which tornado occurred and count the the number of occurrence then put the output in new table in BigQuery.

Prerequisite for Beam Pipeline

  1. Maven
  2. IntelliJ
  3. Google cloud SDK
  4. An existing GCP Project
  5. Java 8 JDK and basic java knowledge

Enable BigQuery, Dataflow, and Google Cloud Storage APIs if not already enabled in the API manager. This will take a few minutes.

Copy the Sample Table

  1. Search BigQuery on GCP console and create a dataset under the existing project.
  2. Now visit https://developers.google.com/bigquery/docs/dataset-gsod
  3. Scroll Down, under Sample Tables click on gsod
  4. Copy this table to your newly created dataset. I have highlighted the gsod table below.
Sample tables
In addition to the public datasets, BigQuery provides a limited number of sample tables that you can query. These tables are contained in the bigquery-public-data:samples dataset.

The requirements for querying the BigQuery sample tables are the same as the requirements for querying the public datasets.

The bigquery-public-data:samples dataset includes the following tables:

Name	Description
gsod	Contains weather information collected by NOAA, such as precipitation amounts and wind speeds from late 1929 to early 2010.
github_nested	Contains a timeline of actions such as pull requests and comments on GitHub repositories with a nested schema. Created in September 2012.
github_timeline	Contains a timeline of actions such as pull requests and comments on GitHub repositories with a flat schema. Created in May 2012.
natality	Describes all United States births registered in the 50 States, the District of Columbia, and New York City from 1969 to 2008.
shakespeare	Contains a word index of the works of Shakespeare, giving the number of times each word appears in each corpus.
trigrams	Contains English language trigrams from a sample of works published between 1520 and 2008.
wikipedia	Contains the complete revision history for all Wikipedia articles up to April 2010.

 

Java Beam Code

  1. clone this repo https://github.com/akipriyadarshi/beam_dataflow.git
  2. cd bigquerytest
  3. ls src/main/java/org/apache/beam/examples . Here you can see BigQueryTornadoes.java which is our beam java code. Other java files are sample file downloaded from Apache Beam Website.
  4. We can also see pom.xml which contains the dependencies for cloud, dataflow etc.
package org.apache.beam.examples;

import com.google.api.services.bigquery.model.TableFieldSchema;
import com.google.api.services.bigquery.model.TableRow;
import com.google.api.services.bigquery.model.TableSchema;
import java.util.ArrayList;
import java.util.List;
import org.apache.beam.sdk.Pipeline;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryIO;
import org.apache.beam.sdk.io.gcp.bigquery.BigQueryIO.TypedRead;
import org.apache.beam.sdk.options.Default;
import org.apache.beam.sdk.options.Description;
import org.apache.beam.sdk.options.PipelineOptions;
import org.apache.beam.sdk.options.PipelineOptionsFactory;
import org.apache.beam.sdk.options.Validation;
import org.apache.beam.sdk.transforms.Count;
import org.apache.beam.sdk.transforms.DoFn;
import org.apache.beam.sdk.transforms.PTransform;
import org.apache.beam.sdk.transforms.ParDo;
import org.apache.beam.sdk.values.KV;
import org.apache.beam.sdk.values.PCollection;
import org.apache.beam.vendor.guava.v26_0_jre.com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class BigQueryTornadoes {
  private static final Logger LOG = LoggerFactory.getLogger(BigQueryTornadoes.class);

  // Default to using a 1000 row subset of the public weather station table publicdata:samples.gsod.
  private static final String WEATHER_SAMPLES_TABLE =
      "bigquey:foo.tornado";

  /**
   * Examines each row in the input table. If a tornado was recorded in that sample, the month in
   * which it occurred is.
   */
  static class ExtractTornadoesFn extends DoFn<TableRow, Integer> {
    @ProcessElement
    public void processElement(ProcessContext c) {
      TableRow row = c.element();
      if ((Boolean) row.get("tornado")) {
        c.output(Integer.parseInt((String) row.get("month")));
      }
    }
  }
static class FormatCountsFn extends DoFn<KV<Integer, Long>, TableRow> {
    @ProcessElement
    public void processElement(ProcessContext c) {
      TableRow row =
          new TableRow()
              .set("month", c.element().getKey())
              .set("tornado_count", c.element().getValue());
      c.output(row);
    }
  }
static class CountTornadoes extends PTransform<PCollection<TableRow>, PCollection<TableRow>> {
    @Override
    public PCollection<TableRow> expand(PCollection<TableRow> rows) {

      // row... => month...
      PCollection<Integer> tornadoes = rows.apply(ParDo.of(new ExtractTornadoesFn()));

      // month... => <month,count>...
      PCollection<KV<Integer, Long>> tornadoCounts = tornadoes.apply(Count.perElement());

      // <month,count>... => row...
      PCollection<TableRow> results = tornadoCounts.apply(ParDo.of(new FormatCountsFn()));

      return results;
    }
  }
public interface Options extends PipelineOptions {
    @Description("Table to read from, specified as <project_id>:<dataset_id>.<table_id>")
    @Default.String(WEATHER_SAMPLES_TABLE)
    String getInput();

    void setInput(String value);

    @Description("SQL Query to read from, will be used if Input is not set.")
    @Default.String("")
    String getInputQuery();

    void setInputQuery(String value);

    @Description("Read method to use to read from BigQuery")
    @Default.Enum("EXPORT")
    TypedRead.Method getReadMethod();

    void setReadMethod(TypedRead.Method value);

    @Description("Write method to use to write to BigQuery")
    @Default.Enum("DEFAULT")
    BigQueryIO.Write.Method getWriteMethod();

    void setWriteMethod(BigQueryIO.Write.Method value);

    @Description("Write disposition to use to write to BigQuery")
    @Default.Enum("WRITE_TRUNCATE")
    BigQueryIO.Write.WriteDisposition getWriteDisposition();

    void setWriteDisposition(BigQueryIO.Write.WriteDisposition value);

    @Description("Create disposition to use to write to BigQuery")
    @Default.Enum("CREATE_IF_NEEDED")
    BigQueryIO.Write.CreateDisposition getCreateDisposition();

    void setCreateDisposition(BigQueryIO.Write.CreateDisposition value);

    @Description(
        "BigQuery table to write to, specified as "
            + "<project_id>:<dataset_id>.<table_id>. The dataset must already exist.")
    @Validation.Required
    String getOutput();

    void setOutput(String value);
  }

  public static void applyBigQueryTornadoes(Pipeline p, Options options) {
    // Build the table schema for the output table.
    List<TableFieldSchema> fields = new ArrayList<>();
    fields.add(new TableFieldSchema().setName("month").setType("INTEGER"));
    fields.add(new TableFieldSchema().setName("tornado_count").setType("INTEGER"));
    TableSchema schema = new TableSchema().setFields(fields);

    TypedRead<TableRow> bigqueryIO;
    if (!options.getInputQuery().isEmpty()) {
      bigqueryIO =
          BigQueryIO.readTableRows()
              .fromQuery(options.getInputQuery())
              .usingStandardSql()
              .withMethod(options.getReadMethod());
    } else {
      bigqueryIO =
          BigQueryIO.readTableRows().from(options.getInput()).withMethod(options.getReadMethod());

      // Selected fields only applies when using Method.DIRECT_READ and
      // when reading directly from a table.
      if (options.getReadMethod() == TypedRead.Method.DIRECT_READ) {
        bigqueryIO = bigqueryIO.withSelectedFields(Lists.newArrayList("month", "tornado"));
      }
    }

    PCollection<TableRow> rowsFromBigQuery = p.apply(bigqueryIO);

    rowsFromBigQuery
        .apply(new CountTornadoes())
        .apply(
            BigQueryIO.writeTableRows()
                .to(options.getOutput())
                .withSchema(schema)
                .withCreateDisposition(options.getCreateDisposition())
                .withWriteDisposition(options.getWriteDisposition())
                .withMethod(options.getWriteMethod()));
  }

  public static void runBigQueryTornadoes(Options options) {
    LOG.info("Running BigQuery Tornadoes with options " + options.toString());
    Pipeline p = Pipeline.create(options);
    applyBigQueryTornadoes(p, options);
    p.run().waitUntilFinish();
  }

  public static void main(String[] args) {
    Options options = PipelineOptionsFactory.fromArgs(args).withValidation().as(Options.class);

    runBigQueryTornadoes(options);
  }
}

Change the value of variable WEATHER_SAMPLES_TABLE according to your project(projectid:datasetid.tableid)

 

Ready to gain a competitive advantage with Future Ready Emerging Technologies?

LET'S INITIATE A PARTNERSHIP

 

Configuring the Service Account

  1. Search IAM & Admin on the console and click IAM.
  2. Now for Compute Engine default service account click on pencil symbol on right for adding roles.
  3. Add roles -> Dataflow Admin, BigQuery Admin, Storage Admin
  4. Now in IAM & Admin click Service Accounts, for the Compute Engine default service account click on Actions(three dots) and click on Manage Keys. Download the JSON.
  5. Run the following command on terminal and provide your own JSON file path which you have downloaded, Put your project and service account email
  6. . gcloud auth activate-service-account test-service-account@google.com –key-file=/path/key.json –project=testproject

 

 

Executing the Pipeline for Beam

  1. Open the project in IntelliJ
  2. Run the following export command(number 3) on IntelliJ terminal. Put the path of your downloaded json.
  3. export GOOGLE_APPLICATION_CREDENTIALS=”/home/knoldus/Downloads/project1-318909-33dd2dc6f789.json”
  4. Search Cloud Storage on GCP Console. Create two new buckets. create temp folder inside each bucket.
  5. Run the below command(number 6) on IntelliJ terminal. change the values of options according to your project(change project, gcpTempLocation, tempLocation, output-> where you want the new output table to get created)

Run the pipeline using below command:-

 mvn compile exec:java -Dexec.mainClass=org.apache.beam.examples.BigQueryTornadoes -Dexec.args="--runner=DataflowRunner --project=bigquey --region=us-central1 --gcpTempLocation=gs://apbucket2/tmp --tempLocation=gs://apbucket2/tmp --input=foo.tornado --output=foo.tornado_result" -Pdataflow-runner 

 

Wait for some time to get it build. It took around 15 minutes for me. check for new table which will contain the number of tornadoes occurred in each month.

You can visit https://blog.knoldus.com/big-data-processing-with-apache-beam/ for more details

Original article source at: https://blog.knoldus.com/

#bigquery #write 

How to Read From one Table and Write To another in BigQuery

Hacer una grabadora de pantalla en Python

La biblioteca Python pyautogui es una biblioteca de automatización que permite el control del mouse y el teclado. O podemos decir que nos facilita automatizar el movimiento del ratón y del teclado para establecer la interacción con la otra aplicación mediante el script de Python. En este tutorial, usaremos esta API para tomar capturas de pantalla y luego usaremos otras bibliotecas para encadenar esos programas de pantalla y crear una grabadora de pantalla. Para realizar la instalación pyautogui en su entorno de Python, ejecute el siguiente comando pip install:

Instalar Pyautogui

pip install pyautogui

Módulos necesarios

  • Numpy: para instalar Numpy, escriba el siguiente comando en la terminal.
pip install numpy
  • pyautogui: para instalar pyautogui, escriba el siguiente comando en la terminal.
pip install pyautogui
  • OpenCV: para instalar OpenCV, escriba el siguiente comando en la terminal.
pip install opencv-python

Comencemos con la importación de los módulos requeridos.

import cv2 as cv
import pyautogui
import numpy as np

Ahora, obtengamos el tamaño de pantalla de nuestra pantalla usando pyautogui. size() función.

#(width,height)
screen_size=pyautogui.size()

A continuación, debemos inicializar el VideoWriter() objeto que escribirá los cuadros de video.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi es el nombre del archivo del video que vamos a grabar.
  • cv.VideoWriter_fourcc(*'MJPG') establecerá el código de cuatro caracteres que comprime los fotogramas.
  • 20 es la velocidad de fotogramas del flujo de vídeo.
  • screen_size es la altura y el ancho del cuadro de video.

Ahora, necesitamos crear un bucle que capture la captura de pantalla de la pantalla y escriba esas imágenes en el video objeto.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • La screenshot() función capturará la pantalla.
  • array(screen_shot_img) convertirá screen_shot_image en una matriz numpy porque se supone que OpenCV funciona con matrices numpy.
  • cvtColor() cambiará el formato de color de la imagen de BGR a RGB porque OpenCV, por defecto, escribe las imágenes en formato BRG, por lo que es importante convertirlas a RGB.
  • La write(frame) función escribirá el marco en el objeto de video.
  • imshow() mostrará una grabación de video en vivo. Para un mejor rendimiento, puede minimizar la ventana del cuadro de grabación.
  • Para cerrar la grabación de pantalla, presione "q" en la pantalla de grabación en vivo o elimine el programa escribiendo CTRL+Z.

Ahora junta todo el código y ejecuta.

Código completo:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Ahora puede crear una grabadora de pantalla en Python con las instrucciones anteriores. ¡¡¡Feliz codificación!!!

Faire un enregistreur d'écran en Python

La bibliothèque Python pyautogui est une bibliothèque d'automatisation qui permet le contrôle de la souris et du clavier. Ou nous pouvons dire que cela nous facilite d'automatiser le mouvement de la souris et du clavier pour établir l'interaction avec l'autre application en utilisant le script Python. Dans ce didacticiel, nous utiliserons cette API pour prendre des captures d'écran, puis utiliserons d'autres bibliothèques pour enchaîner ces écrans et créer un enregistreur d'écran. Pour installer pyautogui pour votre environnement Python, exécutez la commande pip install suivante :

Installer Pyautogui

pip install pyautogui

Modules nécessaires

  • Numpy : Pour installer Numpy, tapez la commande ci-dessous dans le terminal.
pip install numpy
  • pyautogui : pour installer pyautogui, tapez la commande ci-dessous dans le terminal.
pip install pyautogui
  • OpenCV : Pour installer OpenCV, tapez la commande ci-dessous dans le terminal.
pip install opencv-python

Commençons par importer les modules requis.

import cv2 as cv
import pyautogui
import numpy as np

Maintenant, obtenons la taille d'écran de notre affichage en utilisant le pyautogui. size() fonction.

#(width,height)
screen_size=pyautogui.size()

Ensuite, nous devons initialiser l' VideoWriter() objet qui écrira les images vidéo.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi est le nom du fichier de la vidéo que nous allons enregistrer.
  • cv.VideoWriter_fourcc(*'MJPG') définira le code à quatre caractères qui compresse les images.
  • 20 est le framerate du flux vidéo.
  • screen_size est la hauteur et la largeur de l'image vidéo.

Maintenant, nous devons créer une boucle qui capturera la capture d'écran de l'affichage et écrira ces images dans l' video objet.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • La screenshot() fonction capturera l'écran.
  • array(screen_shot_img) convertira le screen_shot_image en un tableau numpy car OpenCV est censé fonctionner avec des tableaux numpy.
  • cvtColor() changera le format de couleur de l'image de BGR à RVB car OpenCV, par défaut, écrit les images au format BRG, il est donc important de les convertir en RVB.
  • La write(frame) fonction écrira l'image dans l'objet vidéo.
  • imshow() affichera un enregistrement vidéo en direct. Pour de meilleures performances, vous pouvez réduire la fenêtre d'image d'enregistrement.
  • Pour fermer l'enregistrement d'écran, appuyez sur "q" sur l'écran d'enregistrement en direct ou arrêtez le programme en tapant CTRL + Z.

Maintenant, rassemblez tout le code et exécutez-le.

Code complet :

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Vous pouvez maintenant créer un enregistreur d'écran en Python avec les instructions ci-dessus. Bon codage !!!

中條 美冬

1664975766

Python でスクリーン レコーダーを作成する

Python pyautogui ライブラリは、マウスとキーボードの制御を可能にする自動化ライブラリです。または、マウスとキーボードの動きを自動化して、Python スクリプトを使用して他のアプリケーションとの対話を確立することが容易になると言えます。このチュートリアルでは、この API を使用してスクリーンショットを撮り、他のライブラリを使用してそれらのスクリーン ショーを連鎖させ、スクリーン レコーダーを作成します。Python 環境用にインストールするpyautogui には、次の pip install コマンドを実行します。

Pyautogui をインストールする

pip install pyautogui

必要なモジュール

  • Numpy: Numpyをインストールするには、ターミナルで次のコマンドを入力します。
pip install numpy
  • pyautogui: pyautoguiをインストールするには、ターミナルで次のコマンドを入力します。
pip install pyautogui
  • OpenCV: OpenCVをインストールするには、ターミナルで次のコマンドを入力します。
pip install opencv-python

必要なモジュールのインポートから始めましょう。

import cv2 as cv
import pyautogui
import numpy as np

それでは、pyautogui を使用してディスプレイの画面サイズを取得しましょう。size() 関数。

#(width,height)
screen_size=pyautogui.size()

次に、VideoWriter() ビデオ フレームを書き込むオブジェクトを初期化する必要があります。

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi は、記録するビデオのファイル名です。
  • cv.VideoWriter_fourcc(*'MJPG') フレームを圧縮する 4 文字のコードを設定します。
  • 20 ビデオストリームのフレームレートです。
  • screen_size ビデオ フレームの高さと幅です。

ここで、ディスプレイのスクリーンショットをキャプチャし、それらの画像をvideo オブジェクトに書き込むループを作成する必要があります。

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • このscreenshot() 関数は画面をキャプチャします。
  • array(screen_shot_img) OpenCVはnumpy配列で動作するはずなので、screen_shot_imageをnumpy配列に変換します。
  • cvtColor() OpenCVはデフォルトで画像をBRG形式で書き込むため、画像の色形式をBGRからRGBに変更します。したがって、それらをRGBに変換することが重要です。
  • このwrite(frame) 関数は、フレームをビデオ オブジェクトに書き込みます。
  • imshow() ライブビデオ録画が表示されます。パフォーマンスを向上させるために、レコーディング フレーム ウィンドウを最小化できます。
  • 画面記録を閉じるには、ライブ記録画面で「q」を押すか、CTRL+Z を入力してプログラムを強制終了します。

すべてのコードをまとめて実行します。

完全なコード:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

上記の手順に従って、Python でスクリーン レコーダーを作成できます。ハッピーコーディング!!!


 

Сделать средство записи экрана на Python

Библиотека Python pyautogui — это библиотека автоматизации, позволяющая управлять мышью и клавиатурой. Или мы можем сказать, что это помогает нам автоматизировать движение мыши и клавиатуры, чтобы установить взаимодействие с другим приложением с помощью скрипта Python. В этом руководстве мы будем использовать этот API для создания снимков экрана, а затем использовать другие библиотеки для объединения этих экранных изображений и создания средства записи экрана. Чтобы установить pyautogui для вашей среды Python, выполните следующую команду pip install:

Установить Пиавтоги

pip install pyautogui

Необходимые модули

  • Numpy: чтобы установить Numpy, введите в терминале приведенную ниже команду.
pip install numpy
  • pyautogui: чтобы установить pyautogui, введите в терминале приведенную ниже команду.
pip install pyautogui
  • OpenCV: чтобы установить OpenCV, введите в терминале приведенную ниже команду.
pip install opencv-python

Начнем с импорта необходимых модулей.

import cv2 as cv
import pyautogui
import numpy as np

Теперь давайте получим размер экрана нашего дисплея с помощью pyautogui. size() функция.

#(width,height)
screen_size=pyautogui.size()

Далее нам нужно инициализировать VideoWriter() объект, который будет записывать видеокадры.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi это имя файла видео, которое мы будем записывать.
  • cv.VideoWriter_fourcc(*'MJPG') установит четырехсимвольный код, сжимающий кадры.
  • 20 частота кадров видеопотока.
  • screen_size высота и ширина видеокадра.

Теперь нам нужно создать цикл, который будет делать снимок экрана дисплея и записывать эти изображения в video объект.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • Функция screenshot() захватит экран.
  • array(screen_shot_img) преобразует screen_shot_image в массив numpy, потому что OpenCV должен работать с массивами numpy.
  • cvtColor() изменит цветовой формат изображения с BGR на RGB, потому что OpenCV по умолчанию записывает изображения в формате BRG, поэтому важно преобразовать их в RGB.
  • Функция write(frame) запишет кадр в видеообъект.
  • imshow() отобразит видеозапись в реальном времени. Для лучшей производительности вы можете свернуть окно кадра записи.
  • Чтобы закрыть запись экрана, либо нажмите «q» на экране записи в реальном времени, либо завершите программу, набрав CTRL+Z.

Теперь соедините весь код и выполните его.

Полный код:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Теперь вы можете создать средство записи экрана на Python с помощью приведенных выше инструкций. Удачного кодирования!!!

Duck Hwan

1664964857

파이썬으로 스크린 레코더 만들기

Python pyautogui 라이브러리는 마우스 및 키보드 제어를 허용하는 자동화 라이브러리입니다. 또는 Python 스크립트를 사용하여 다른 응용 프로그램과의 상호 작용을 설정하기 위해 마우스와 키보드의 움직임을 자동화하는 것을 용이하게 한다고 말할 수 있습니다. 이 튜토리얼에서는 이 API를 사용하여 스크린샷을 찍은 다음 다른 라이브러리를 사용하여 해당 화면 쇼를 연결하고 화면 레코더를 만듭니다. Python 환경에 설치하려면 pyautogui 다음 pip install 명령을 실행합니다.

Pyautogui 설치

pip install pyautogui

필요한 모듈

  • Numpy: Numpy 를 설치하려면 터미널에 아래 명령을 입력하십시오.
pip install numpy
  • pyautogui: pyautogui 를 설치하려면 터미널에 아래 명령을 입력하십시오.
pip install pyautogui
  • OpenCV: OpenCV 를 설치하려면 터미널에 아래 명령을 입력하십시오.
pip install opencv-python

필요한 모듈을 가져오는 것부터 시작하겠습니다.

import cv2 as cv
import pyautogui
import numpy as np

이제 pyautogui를 사용하여 디스플레이의 화면 크기를 알아보겠습니다. size() 기능.

#(width,height)
screen_size=pyautogui.size()

VideoWriter() 다음으로, 비디오 프레임을 기록할 객체 를 초기화해야 합니다 .

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi 녹화할 비디오의 파일 이름입니다.
  • cv.VideoWriter_fourcc(*'MJPG') 프레임을 압축하는 4자리 코드를 설정합니다.
  • 20 비디오 스트림의 프레임 속도입니다.
  • screen_size 비디오 프레임의 높이와 너비입니다.

video 이제 디스플레이의 스크린샷을 캡처하고 해당 이미지를 개체 에 쓰는 루프를 만들어야 합니다.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • screenshot() 기능은 화면을 캡처합니다.
  • array(screen_shot_img) OpenCV는 numpy 배열과 함께 작동해야 하기 때문에 screen_shot_image를 numpy 배열로 변환합니다.
  • cvtColor() OpenCV는 기본적으로 BRG 형식으로 이미지를 기록하므로 이미지의 색상 형식을 BGR에서 RGB로 변경하므로 RGB로 변환하는 것이 중요합니다.
  • write(frame) 함수는 프레임을 비디오 객체에 기록합니다.
  • imshow() 라이브 비디오 녹화를 표시합니다. 더 나은 성능을 위해 녹화 프레임 창을 최소화할 수 있습니다.
  • 화면 녹화를 닫으려면 라이브 녹화 화면에서 "q"를 누르거나 CTRL+Z를 입력하여 프로그램을 종료합니다.

이제 모든 코드를 모아서 실행하십시오.

전체 코드:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

이제 위의 지침에 따라 Python에서 스크린 레코더를 만들 수 있습니다. 즐거운 코딩!!!

Erstellen Sie einen Bildschirmrekorder in Python

Die Python-Pyautogui-Bibliothek ist eine Automatisierungsbibliothek, die die Maus- und Tastatursteuerung ermöglicht. Oder wir können sagen, dass es uns erleichtert, die Bewegung von Maus und Tastatur zu automatisieren, um die Interaktion mit der anderen Anwendung mithilfe des Python-Skripts herzustellen. In diesem Tutorial verwenden wir diese API, um Screenshots zu machen, und verwenden dann andere Bibliotheken, um diese Bildschirmshows zu verketten und einen Bildschirmrekorder zu erstellen. Führen Sie zur Installation pyautogui für Ihre Python-Umgebung den folgenden Pip-Installationsbefehl aus:

Pyautogui installieren

pip install pyautogui

Module benötigt

  • Numpy: Um Numpy zu installieren, geben Sie den folgenden Befehl im Terminal ein.
pip install numpy
  • pyautogui: Um pyautogui zu installieren, geben Sie den folgenden Befehl im Terminal ein.
pip install pyautogui
  • OpenCV: Um OpenCV zu installieren, geben Sie den folgenden Befehl im Terminal ein.
pip install opencv-python

Beginnen wir mit dem Import der benötigten Module.

import cv2 as cv
import pyautogui
import numpy as np

Lassen Sie uns nun die Bildschirmgröße unseres Displays mit pyautogui abrufen. size() Funktion.

#(width,height)
screen_size=pyautogui.size()

Als nächstes müssen wir das VideoWriter() Objekt initialisieren, das die Videoframes schreiben wird.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi ist der Dateiname des Videos, das wir aufnehmen werden.
  • cv.VideoWriter_fourcc(*'MJPG') setzt den vierstelligen Code, der die Frames komprimiert.
  • 20 ist die Framerate des Videostreams.
  • screen_size ist die Höhe und Breite des Videorahmens.

Jetzt müssen wir eine Schleife erstellen, die den Screenshot der Anzeige erfasst und diese Bilder in das video Objekt schreibt.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • Die screenshot() Funktion erfasst den Bildschirm.
  • array(screen_shot_img) konvertiert das screen_shot_image in ein numpy-Array, da OpenCV mit numpy-Arrays arbeiten soll.
  • cvtColor() ändert das Farbformat des Bildes von BGR in RGB, da OpenCV standardmäßig Bilder im BRG-Format schreibt, daher ist es wichtig, sie in RGB zu konvertieren.
  • Die write(frame) Funktion schreibt den Frame in das Videoobjekt.
  • imshow() zeigt eine Live-Videoaufnahme an. Für eine bessere Leistung können Sie das Aufzeichnungsbildfenster minimieren.
  • Um die Bildschirmaufzeichnung zu schließen, drücken Sie entweder „q“ auf dem Live-Aufzeichnungsbildschirm oder beenden Sie das Programm, indem Sie STRG+Z eingeben.

Setzen Sie nun den gesamten Code zusammen und führen Sie ihn aus.

Vollständiger Code:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Jetzt können Sie mit den obigen Anweisungen einen Bildschirmrekorder in Python erstellen. Viel Spaß beim Codieren!!!

Faça um gravador de tela em Python

A biblioteca Python pyautogui é uma biblioteca de automação que permite o controle do mouse e do teclado. Ou podemos dizer que nos facilita automatizar o movimento do mouse e teclado para estabelecer a interação com o outro aplicativo usando o script Python. Neste tutorial, usaremos essa API para fazer capturas de tela e, em seguida, usar outras bibliotecas para encadear essas apresentações de tela e criar um gravador de tela. Para instalar pyautogui para seu ambiente Python, execute o seguinte comando pip install:

Instalar Pyautogui

pip install pyautogui

Módulos necessários

  • Numpy: Para instalar o Numpy digite o comando abaixo no terminal.
pip install numpy
  • pyautogui: Para instalar o pyautogui digite o comando abaixo no terminal.
pip install pyautogui
  • OpenCV: Para instalar o OpenCV digite o comando abaixo no terminal.
pip install opencv-python

Vamos começar importando os módulos necessários.

import cv2 as cv
import pyautogui
import numpy as np

Agora, vamos obter o tamanho da tela do nosso display usando o pyautogui. size() função.

#(width,height)
screen_size=pyautogui.size()

Em seguida, precisamos inicializar o VideoWriter() objeto que escreverá os quadros de vídeo.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi é o nome do arquivo do vídeo que iremos gravar.
  • cv.VideoWriter_fourcc(*'MJPG') definirá o código de quatro caracteres que compacta os quadros.
  • 20 é a taxa de quadros do videostream.
  • screen_size é a altura e a largura do quadro de vídeo.

Agora, precisamos criar um loop que capturará a captura de tela da tela e gravará essas imagens no video objeto.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • A screenshot() função irá capturar a tela.
  • array(screen_shot_img) irá converter o screen_shot_image em um array numpy porque o OpenCV deve funcionar com arrays numpy.
  • cvtColor() mudará o formato de cor da imagem de BGR para RGB porque o OpenCV, por padrão, grava imagens no formato BRG, por isso é importante convertê-las em RGB.
  • A write(frame) função escreverá o quadro no objeto de vídeo.
  • imshow() exibirá uma gravação de vídeo ao vivo. Para um melhor desempenho, você pode minimizar a janela do quadro de gravação.
  • Para fechar a gravação da tela, pressione "q" na tela de gravação ao vivo ou encerre o programa digitando CTRL+Z.

Agora junte todo o código e execute.

Código Completo:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Agora você pode criar um gravador de tela em Python com as instruções acima. Boa Codificação!!!

CODE VN

CODE VN

1664944336

Tạo trình ghi màn hình bằng Python

Thư viện pyautogui trong Python là một thư viện tự động hóa cho phép điều khiển chuột và bàn phím. Hoặc chúng ta có thể nói rằng nó tạo điều kiện cho chúng ta tự động hóa chuyển động của chuột và bàn phím để thiết lập tương tác với ứng dụng khác bằng cách sử dụng tập lệnh Python. Trong hướng dẫn này, chúng tôi sẽ sử dụng API này để chụp ảnh màn hình và sau đó sử dụng các thư viện khác để xâu chuỗi các màn hình đó và tạo trình ghi màn hình. Để cài đặt pyautogui cho môi trường Python của bạn, hãy chạy lệnh cài đặt pip sau:

Cài đặt Pyautogui

pip install pyautogui

Mô-đun cần thiết

  • Numpy: Để cài đặt Numpy, gõ lệnh dưới đây trong terminal.
pip install numpy
  • pyautogui: Để cài đặt pyautogui, gõ lệnh dưới đây trong terminal.
pip install pyautogui
  • OpenCV: Để cài đặt OpenCV, hãy nhập lệnh dưới đây vào terminal.
pip install opencv-python

Hãy bắt đầu với việc nhập các mô-đun cần thiết.

import cv2 as cv
import pyautogui
import numpy as np

Bây giờ, hãy lấy kích thước màn hình của màn hình bằng cách sử dụng pyautogui. size() hàm số.

#(width,height)
screen_size=pyautogui.size()

Tiếp theo, chúng ta cần khởi tạo VideoWriter() đối tượng sẽ ghi các khung hình video.

#initialize the object
video = cv.VideoWriter('Recording.avi', 
                        cv.VideoWriter_fourcc(*'MJPG'), 
                        20, 
                        screen_size)
  • Recording.avi là tên tệp của video mà chúng tôi sẽ quay.
  • cv.VideoWriter_fourcc(*'MJPG') sẽ đặt mã bốn ký tự nén các khung.
  • 20 là tốc độ khung hình của luồng video.
  • screen_size là chiều cao và chiều rộng của khung video.

Bây giờ, chúng ta cần tạo một vòng lặp sẽ chụp ảnh màn hình của màn hình và ghi những hình ảnh đó vào video đối tượng.

print("Recording.....")
while True:
    #take screenshot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()
  • Chức screenshot() năng sẽ chụp màn hình.
  • array(screen_shot_img) sẽ chuyển đổi screen_shot_image thành một mảng numpy vì OpenCV được cho là hoạt động với các mảng numpy.
  • cvtColor() sẽ thay đổi định dạng màu của hình ảnh từ BGR sang RGB vì OpenCV, theo mặc định, ghi hình ảnh ở định dạng BRG, vì vậy điều quan trọng là phải chuyển đổi chúng thành RGB.
  • Hàm write(frame) sẽ ghi khung vào đối tượng video.
  • imshow() sẽ hiển thị một bản ghi video trực tiếp. Để có hiệu suất tốt hơn, bạn có thể thu nhỏ cửa sổ khung ghi âm.
  • Để đóng ghi màn hình, nhấn "q" trên màn hình ghi trực tiếp hoặc tắt chương trình bằng cách gõ CTRL + Z.

Bây giờ đặt tất cả các mã lại với nhau và thực thi.

Mã đầy đủ:

import cv2 as cv
import pyautogui
import numpy as np

#(width,height)
screen_size=pyautogui.size()

#initialize the object
video = cv.VideoWriter('Recording.avi',  
                         cv.VideoWriter_fourcc(*'MJPG'), 
                         20, screen_size)

print("Recording.....")
while True:
    #click screen shot
    screen_shot_img = pyautogui.screenshot()

    #convert into array
    frame = np.array(screen_shot_img)

    #change from BGR to RGB
    frame = cv.cvtColor(frame, cv.COLOR_BGR2RGB)

    #write frame
    video.write(frame)

    #display the live recording 
    cv.imshow("Recording Frame(Minimize it)", frame)    
    if cv.waitKey(1) == ord("q"):
        break

cv.destroyAllWindows()
video.release()

Bây giờ bạn có thể tạo trình ghi màn hình bằng Python với các hướng dẫn ở trên. Chúc bạn mã hóa vui vẻ !!!