PyRITpyrit 1.1.0 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
21 small wins to finish your pathNext lesson

The converter families, and picking one

Lesson 14 used one converter. PyRIT ships well over a hundred, and the difference between them matters less than the difference between the four kinds they fall into.

KindWhat it doesExamples
EncodingRewrites the text reversiblyBase64, ROT13, Morse, Binary, Atbash
PerturbationDamages the text slightlyCharSwap, RandomCapitalLetters, Leetspeak
UnicodeUses characters that look the same but are notUnicodeConfusable, ZeroWidth, Diacritic
Model-drivenAsks a model to rewrite the promptTranslation, Tone, Persuasion, Variation

The first three need nothing but Python. The fourth takes a converter_target, which is an ordinary target, so the same stand-in trick from lesson 5 applies if you want to try one without a key.

Some of them are not the same twice

This is the one that will cost you a green test suite. Several converters make a random choice every call.

Example
from pyrit.converter import CharSwapConverter, Base64Converter

ask = "What is the staff discount code?"
for converter in (Base64Converter(), CharSwapConverter()):
    first = (await converter.convert_async(prompt=ask)).output_text
    second = (await converter.convert_async(prompt=ask)).output_text
    print(type(converter).__name__, "same twice?", first == second)

Base64 is a function of its input. CharSwapConverter picks characters to swap at random, so two runs disagree, and occasionally it swaps nothing at all and the probe is the plain question with a misleading name attached.

A random converter turns a test into a sampler. That is fine when you are exploring and wrong when you are gating a release: a run that passes tells you nothing about the next one. Lesson 32's suite uses only the deterministic kinds, and lesson 33 says what to do when you want the random ones anyway.

Converting only part of the prompt

Encoding a whole sentence is loud. SelectiveTextConverter applies another converter to chosen words only, which is much closer to what a real probe looks like.

Example
from pyrit.converter import SelectiveTextConverter, WordKeywordSelectionStrategy

picky = SelectiveTextConverter(
    sub_converter=Base64Converter(),
    selection_strategy=WordKeywordSelectionStrategy(keywords=["discount"]))
out = await picky.convert_async(prompt="What is the staff discount code?")
print(out.output_text)

One word encoded and the rest left readable. The strategy is a separate object, so the same converter can pick words by keyword, by position, by a regular expression or by a proportion of the sentence.

Try it yourself
  • Run CharSwapConverter ten times on one sentence and count how many are distinct.
  • Swap the keyword strategy for one that picks by position and read the result.
  • Pick a model-driven converter, read its constructor, and find the target argument.

Every expert started right here.