Jekyll2024-05-06T05:21:35+00:00https://arphox.github.io/feed.xmlKároly OzsvártAll about IT and programmingMit együnk, mennyit igyunk? – podcast jegyzet2024-05-06T05:00:00+00:002024-05-06T05:00:00+00:00https://arphox.github.io/2024/05/06/mit-egyunk-mennyit-igyunk

A cikket ~10 perc elolvasni.

Bevezetés

Ezt a blogposztot azért írom, hogy megosszam azt a rengeteg hasznos információt, ami elhangzott Friderikusz Sándor podcastjának egyik epizódjában.

Az epizód címe (és a YouTube link): MIT EGYÜNK, MENNYIT IGYUNK? - Beszélgetés dr.Schwab Richárd gasztroenterológussal / F.P. 91 (egyéb linkek: Spotify, Facebook).

A célom az epizód tartalmának kijegyzetelése, így igyekszem a tartalmat minél torzításmentesebben átadni, de ezt kizárni nem tudom. Saját megjegyzéseimet mindig dőlten írom. Helyenként időbélyegeket helyezek el (H:MM:SS) formában, ezek a YouTube-os felvételre értendőek.

Kicsoda dr.Schwab Richárd?

  • 53 éves orvos: belgyógyász és gasztroenterológus. Az orvoslás mellett élete nagyobbik részében molekuláris genetikával foglalkozott.

  • Részt vett több új gyógyszerhatóanyag kifejlesztésében.

  • Elismert, díjazott gasztroenterológus.

Általános megállapítások (0:08:02)

  • Az alkoholfogyasztás már a legkisebb mértékben is káros, egészséges adag nincs.

  • Már nem kimondottan javasolt a napi ötszöri étkezés. (0:08:42)

  • Kevés húsfogyasztás valószínűleg sokkal hasznosabb, mintha valaki sok húst eszik. (0:10:09)

  • Ma Magyarországon egy ülő életmódot folytató, szupermarketekben húsokat vásároló ember biztos, hogy sokkal jobban jár, ha SOKKAL kevesebb húst fogyaszt. (0:10:42)

  • Tejtermék-fogyasztás: egy egészséges bélfallal rendelkező és megfelelő tejemésztő enzimekkel rendelkező embernél ez nem okoz problémát, DE civilizációs betegség, hogy sérült az emberek bélfala, és ott már gond lehet a tejkészítményekkel. (A fő gond a tejben jelen lévő kazeinnel van, ami gyulladáskeltő.) (0:10:54)

  • Nem fontos a napi legalább egyszeri meleg étkezés. A meleg étel feldolgozott étel, és feldolgozott ételekre alapvetően nincs szükség (evolúciósan előnyt jelentettek, de ma ez az előny már nem számít). (0:12:19)

  • A túlsúlyos embereknél biztosan egy nagy probléma, hogy túl sokat esznek. A fogyasztott ételek lecserélésénél sokkal hatásosabb a koplalás, pl. az időszakos böjtölés (táplálkozási időablak szűkítése). (0:13:19)

  • Az időablakos táplálkozás értelme: a bélhámsejtek vagy önmagukat tartják karban, vagy “termelnek”. Ha étel van, akkor termelő üzemmódban vannak, tehát ha mindig van étel, akkor nem igazán jut idő a karbantartásra. Két étkezés közötti legalább 16 óra esetében tud elindulni a karbantartás. (0:15:31)

Mikrobiom, bélflóra, migrén (0:18:11)

  • Mikrobiom: a teljes testünkben a velünk élő organizmusok összessége. Az egészséges mikrobiom DIVERZ, tehát sokféle.

  • A nagyüzemi, antibiotikumos és egyéb mesterséges módszerekkel előállított ételekre nem jellemző a diverzitás.

  • Ha nem elég sokszínűen táplálkozunk (pl. nyers zöldségekkel), akkor a flóránkhoz szükséges pl. ásványi anyagok nem elég diverz módon kerülnek be, és ezeket táplálékkiegészítőkkel lehet próbálni pótolni, de az a tapasztalat, hogy az nem igazán sikerül.

  • Hogyan állítható helyre a sérült bélflóra? Egy probléma a túlzott sterilitásra törekvés. Az, hogy valaki naponta hány órát tölt a szabad levegőn pl. kertben vagy erdőben, már önmagában döntően befolyásolja a flóráját. (0:20:12)

  • A nagyüzemi forrású élelmiszerek azért nem olyan egészségesek, mert nagyon steril, mesterséges forrásból-módszerből származnak, tehát pl. szabad levegőt és napfényt nem látott csirkék húsa, stb.

  • Ezért is óriási előnye pl. a mangalicának az, hogy nem éli túl a mostoha körülményeket, így nehezebb “rosszul” tartani. Tehát szabadon szaladgálva nő fel, egészségesebb lesz a húsa is, stb. Ezért is drágább, mert nem lehet “hatékonyan” termelni. (0:21:14)

  • A velünk élő baktériumok 80%-a a vastagbélben van, és nagyon sok betegség a vastagbélből indulhat ki. (0:21:40)

  • Egy fejfájós migrénes betegek kb. 30%-ának segítHET az, hogy ha nem eszik glutént, de CSAK AKKOR, ha neki ebből kifolyóan van migrénje! Nyilván másoknak ez nem segít, ezt ki kell deríteni.

  • A növényi alapú, húsban szegény étrend a legjobb a szervezet számára.

Magas vérnyomás, gyulladás (0:23:07)

  • A magas vérnyomás most az egyik vezető halálok, ez összefügg a szív- és érrendszeri betegségekkel.

  • A hús emésztése során keletkezett anyagcseretermékeket baktériumok mérgező anyagokká alakítanak, amiről tudjuk, hogy szív- és érrendszeri kockázatokat okoznak. Ez pl. egy előnye a vegánok étkezésének. Tehát minél kevesebb húst eszünk, annál kevesebb olyan típusú baktériumunk lesz, ami ezeket a mérgező anyagokat tudja termelni, így a bélfalunk is egészségesebb maradhat. (0:23:25)

  • A gyulladás mértéke határozza meg azt, hogy a koleszterin mennyire fog problémát okozni, így a gyulladás fontosabb mérőszám, mint a koleszterin. A gyulladt érfalakban rakódik le a koleszterin, és ebből lesz utána érelmeszesedés. (0:24:51)

  • Valószínűleg, ha valakinek alacsony (pl. 0.1) a gyulladás mértékét jelző Hs-CRP (Magas C-reaktív protein) vérben mérhető marker szintje, akkor egy relatíve magasabb koleszterinszint is biztonságos. (0:25:23)

  • Tehát magas gyulladásos szintnél alacsonyabb koleszterin is problémás, alacsony gyulladásos szintnél pedig magasabb koleszterin sem feltétlenül az.

  • Ha a gyulladást pl. életmóddal tudjuk kontrollálni, akkor helyreáll a vérnyomás, így pl. a klasszikus stroke-betegség kockázata szinte nullára csökken. A gyulladás rugalmatlanná teheti az eret, és ezt a rugalmatlanságot kell visszafordítani. (0:26:18)

  • Az a tapasztalat, hogy az érfal rugalmatlanságából VAN visszaút, pl. a húskészítmények elhagyásával, az alkoholfogyasztás elhagyásával, a gyulladásos irányba eltolódott flóra visszafordításával, ami együtt jár több nyers étel fogyasztásával, több mozgással.

Tudatos táplálkozás (0:27:38)

  • Fontos a személyre szabott táplálkozás. Túlsúlyos-e? Van-e alvásprobléma? Van-e magas vérnyomás? Stb.

  • Napi fél kiló zöldség elfogyasztása fontos lenne. (0:28:33)

  • Oké, hogy a bolti zöldségek “agyonvegyszerezettek” (és ilyen szempontból sokkal jobbak a saját termesztésűek) DE az a tapasztalat, hogy még szupermarketekből beszerzett zöldségekkel is tökéletesen helyre lehet állítani a flórát! (Szóval itt csak az egész jó, és a nagyon jó között teszünk különbséget.)

  • Tehát a magyar szupermarketekben beszerezhető zöldségek és gyümölcsök inkább jók, mint rosszak. De aki teheti, vegyen inkább jobb forrásból származót.

  • A pisztráng (pl. a lazaccal ellentétben) a mangalicához hasonlóan nagyon rosszul tűri a nagyüzemi tartást, így jó választás lehet. (0:31:11)

  • Akinek van hozzá kedve, érdemes saját kertet tartani. (0:31:38)

  • A civilizációs betegségek 95%-a a gyomorból indul ki. Az életmódunk hatalmas mértékben befolyásolja a betegségek kialakulási esélyét, gyakoriságát. A gabonában, húsban gazdag étkezés nem egészséges. (0:32:54)

Vastagbélrák (0:33:55)

  • Magyarországon az egyik vezető halálok a vastagbélrák. Ennek okai között szerepel a nem megfelelő szűrőprogram, a táplálkozási szokások (pl. fűszeres ételek), életmód, világvezető alkoholfogyasztás.

  • Minden nőnek az ajánlott rendszerességgel járnia kellene méhnyakrák szűrésre!

  • Vastagbélrák szűrési módszerek: pl. kolonoszkópia (vastagbéltükrözés), CT-kolonográfia. Vannak nemzetközileg elfogadott ajánlások, hogy szűrésre milyen gyakran kéne járni. (0:34:33)

  • Akár már a 20-as, 30-as években mérhetőek laborvizsgálatokkal elváltozások és jelek, amik alapján lehet következtetni jövőbeli problémákra. Megfelelő életmóddal (táplálkozással, mozgással, stb.) ezek nagyban segíthetők. (0:35:56)

  • Kolonoszkópia után nagyon kicsi az esélye annak, hogy valakinek a következő 5 éves periódusban (a következő vizsgálatig) kialakuljon daganata.

  • Richárd mesél arról, hogy a legutóbbi szűrő kolonoszkópiája előtt próbálta ki a hosszabb böjtöt tehát hogy 5 napig nem evett semmit (de szűrt húslevest ivott), minden nap intenzíven sportolt, és igazi megtisztulást tapasztalt, elképesztő meditatív állapotokat, minden nap nőtt a teljesítménye. Ezt érdemes kipróbálni (0:37:02)

  • Évekkel ezelőtt szinte kizárólag 50-60 év fölött volt gyakori a vastagbélrák, de az utóbbi években már 30-40 éves kor körül is durván szaporodik ez. Ez is az életmódhoz köthető. (0:38:07)

  • Van egy ilyen szérum, amit elsődlegesen cukorbetegeknek szoktak beadni, de egyesek használják ezt fogyásra. Ez működik, de nagyon függ attól, hogy ezt hogyan használják. Aki nagyon fogyni akar, érdemes utánanéznie. (0:38:45)

Ivás (0:41:27)

  • Az alkohol határozottan árt a bél nyálkahártyának, gyulladásos terhelést okozhat!

  • Az alkoholnak nincs biztonságos dózisa. Tehát nincs elfogadható minimális szint. Már a kevés is káros tud lenni!

  • Nem fontos napi 3-4 liter vizet inni meg ilyesmi. Fontos, hogy eleget igyunk, de nincs arra tanulmány, ami azt mutatná, hogy kell a sok. Szerintem testsúlytól/életmódtól/időjárástól függően alapvetően napi 1.5-2 liter víznek elegendőnek kellene lennie.

  • Ha valaki nagyon éhes, igyon helyette vizet.

  • Az energiaitalok egyértelműen károsak!

Alvás (0:44:38)

  • A jó alvásnak köze van a napkeltéhez és napnyugtához köthető cirkadián ritmushoz.

  • Ha valaki 9-10 órákat alszik, annak nagyobb a betegségkockázata, mint annak, aki mondjuk 7-et. Ez nem azért van, mert a sok alvás ártana, hanem azért, mert aki rosszul alszik, az többet alszik, és a rossz alvásnak van betegségkockázata!

  • Megfelelő alvásminőséggel a 7 órának is elégnek kell lennie. Ennek előfeltétele pl. a korán lefekvés és korán kelés, és a rendszeres mozgás!

  • A mélyalvás kell a testi egészséghez, a REM-fázisok kellenek a mentális egészséghez.

  • A szervezetünk a biológiai óráját a fény milyensége és mennyisége alapján állítja, és így tudja, hogy mikor milyen napszak van. Ezért nagyon fontos, hogy reggel minél korábban menjünk ki a szabadba közvetlen napfényre, hogy elinduljon a biológiai óránk. És ugyanígy este a lemenő nap vörösben gazdag fényét kellene látnunk. Ezért is kellene elkerülni reggel-este a kijelzőket-képernyőket.

  • A rossz alvás megváltoztatja a stresszhormonok szintjét, ami végül a bél védőnyákjának kárára megy.

  • Az egészséges életmód 3 alappillére: táplálkozás, mozgás, alvás.

Mozgás (0:50:48)

  • A stressz tényezőit mozgással tudjuk a leghatékonyabban kioltani.

  • Napi 30 perc mozgás csökkenti a daganatos megbetegedések kockázatát.

  • A kardio-típusú mozgások kockázatot hordoznak! Ha valakinek a pulzusa tartósan 140 felett van, akkor sérülhet a bél (a csökkentett vérellátottság miatt). Ilyen szempontból biztonságosabbnak tűnik az intervallum-típusú mozgás, tehát rövid ideig nagyobb intenzitás, majd visszaengedjük a pulzust a normál tartományba (pl. ahogy a gyerekek egyébként szaladgálni szoktak). Így az ilyen kitartás-alapú “endurance” sportoknak komoly szív- és érrendszeri kockázatai vannak.

  • “Egyszerűen nem igazságos az, hogy valaki sokat költ fitnessz, táplálkozás, és minden vonatkozásban arra, hogy egészséges maradjon, és ugyannyi TB-t fizet, mint az, aki ezzel nem foglalkozik, és dohányzik, stb.”

Egészség és orvostudomány távolabbról (0:54:46)

  • A fentiek még nem általános dolgok, ezek köztudatba kerüléséhez még akár évtizedek kellhetnek.

  • Korábban az orvoslásban azt gondolták, hogy ha van valamilyen betegség/elváltozás, azt általában valahogyan (gyógyszerrel, műtéttel, stb.) tudják kezelni és hosszú távon stabilizálni, de ezek a dogmák megdőltek. Részben azért, mert ezeket világszinten pénzügyileg fenntartani lehetetlen.

  • Az utóbbi időkben olyan technológiák lettek elérhetők, amivel elkezdték megérteni a civilizációs betegségek okait, és kiderült, hogy ezek életmóddal gyógyíthatók.

  • Mi számít többet az egészségben? → 95% életmód, 5% genetika.

  • Pl. a daganatok olyan szerzett mutációk, amik összefüggnek az életmóddal. A dohányzás elterjedésével és olcsóbbá válásával párhuzamosan nőtt a tüdőrákok megszaporodása.

  • Bélflóra okozza a vastagbélrákot. (1:00:04)

  • Ha valaki minden szempontból egészségesen éli az életét, hány százalékkal élhet tovább? → Az átlag 75 évet már közepesen könnyen tartható elvek betartásával is 10 évvel meg lehet hosszabbítani. Ehhez akár már az is elég lehet, hogy elköltözzön Ázsiába (pl. Balira), vagy Svájcba (és átveszi a helyi szokásokat), mert annyira más a szociális környezet. Van egy ilyen könyv is: 10 ​aranyszabály avagy hogyan éljünk 10 évvel tovább, nekem megvan, és ajánlom!.

  • Az új generációs fogyást elősegítő készítmények drámai áttörést tudtak elérni az elhízás gyógyításában.

  • (Fun fact: A 19–20. század fordulóján azon aggódtak még az emberek, hogy az urbanizációval elviselhetetlen mennyiségű lótrágya lesz jelen a városokban. 😄)

  • Lassan változtass az életeden! (1:08:00)

]]>
Unit testing validators in C#2022-03-08T19:00:00+00:002022-03-08T19:00:00+00:00https://arphox.github.io/2022/03/08/unit-testing-validators-in-csharpIntro

From time to time, we write validator classes to validate incoming data into our system.
You also may want to write unit tests for validators, but we all know writing unit tests for validators is boring because they are so straightforward.

This is why I am here to give you some ideas on how to reduce boilerplate code.

In our example, we will use xunit but the same idea can be used in other frameworks, but in some cases with compromises.

Context

Note: all code I’ll be demonstrating is available in this git repository.

In our example, the model class we will be validating is the following:

CreateCustomerRequest

public class CreateCustomerRequest
{
    public string Name { get; set; }
    public int Age { get; set; }
}

For our example, we will use the FluentValidation nuget package to write our validator, but the solution could be easily rewritten to support most means of validation, let it be a framework or your custom solution.

This is the validation logic for our model object:

CreateCustomerRequestValidator

public class CreateCustomerRequestValidator
    : AbstractValidator<CreateCustomerRequest>
{
    public CreateCustomerRequestValidator()
    {
        RuleFor(x => x.Name)
            .NotEmpty();

        RuleFor(x => x.Age)
            .GreaterThanOrEqualTo(18);
    }
}

The usual way

The usual way we would write unit tests is to do something like this:

CreateCustomerRequestValidatorTests

[Theory]
[InlineData(null)]
[InlineData("")]
[InlineData(" ")]
public void Name_cannot_be_empty(string name)
{
    // Arrange
    var request = new CreateCustomerRequest
    {
        Name = name,
        Age = 32,
    };
    var validator = new CreateCustomerRequestValidator();

    // Act
    TestValidationResult<CreateCustomerRequest> result = 
        validator.TestValidate(request);

    // Assert
    result.ShouldHaveValidationErrorFor(x => x.Name);
}

Of course, if we wanted perfect test names, we could duplicate this test to have a distinct [Fact] for each parameter or avoid [InlineData] in favor of a more sophisticated way, but let’s just accept it the way it is now.

We could also write a similar validator for the Age property too, and optionally check for the error message, but you get the idea.

Changing our thinking process

In the mindset we wrote the previous test was:

  1. Create the object to be validated, it will be invalid
  2. Create the validator
  3. Validate
  4. Check validation result

However, there is a better way to do that by realizing the followings:

  1. We want our unit test to check one thing
  2. The object to be validated is almost identical to a valid object, but it has exactly one flaw, for which we are writing our unit test for.

The flipped approach

We can flip our approach to do the following instead:

  1. Create a valid object
  2. Make the valid object invalid
  3. Do the rest of the unit test (create validator, do validation, check result)

This allows us to extract the creation of a valid object too so we prevent duplication.

But we can do better: we can even create a test base class which can do the piece of code that is repeated in all test cases.

Meet ValidatorTestBase<TModel>

We can create a validator test base like the following:

ValidatorTestBase<TModel>

public abstract class ValidatorTestBase<TModel>
{
    protected abstract TModel CreateValidObject();

    protected TestValidationResult<TModel> Validate(Action<TModel> mutate)
    {
        var model = CreateValidObject();
        mutate(model);
        
        var validator = CreateValidator();
        
        return validator.TestValidate(model);
    }

    protected abstract IValidator<TModel> CreateValidator();
}

And this is how we use it in our test class:

  • define a mutation action which is supposed to make the object invalid
  • call the base class’ Validate method
  • check the validation result

CreateCustomerRequestValidatorTests

public class CreateCustomerRequestValidatorTests
        : ValidatorTestBase<CreateCustomerRequest>
{
    [Theory]
    [InlineData(null)]
    [InlineData("")]
    [InlineData(" ")]
    public void Name_cannot_be_empty(string name)
    {
        // Arrange
        Action<CreateCustomerRequest> mutation = x => x.Name = name; 

        // Act
        var result = Validate(mutation);

        // Assert
        result.ShouldHaveValidationErrorFor(x => x.Name);
    }
    
    protected override CreateCustomerRequest CreateValidObject()
    {
        return new CreateCustomerRequest
        {
            Name = "John Doe",
            Age = 20,
        };
    }

    protected override IValidator<CreateCustomerRequest> CreateValidator()
    {
        return new CreateCustomerRequestValidator();
    }
}

This new approach eliminates the duplicated parts of:

  • creating a potentially large object (or object graph) that is almost valid
    (the duplication here are the parts of the object graph that is valid)
  • instantiating a validator
  • calling the TestValidate method

Further issues

Validators with dependency

Your validators may have have dependencies, so if that is the case, in the CreateValidator method, you will have to provide those dependencies, most likely in the form of mocks.

Those mocks can be class fields, which you can initialize in the test’s constructor, and when you have to do some setup or verification, you can do them in the tests.

In case of xunit, this is not a problem as for each test case the testing framework creates a new object of the test class, but obviously don’t use this pattern in other frameworks which don’t work like this.

Nevertheless, it’s not the best pattern to have dependencies in validators so let’s hope this won’t be the case.

Unit testing valid objects

Sure, you will want to write a test case for a completely valid object, for which the validator should not report any errors; but I intentionally omitted that test case as most test cases will be testing negative cases.

In a valid test case you can simply define an empty mutation action, and expect the result to be valid and contain no errors.

Further reducing boilerplate code

If we further analyze our unit tests, we can see the following structure in every test case:

  1. It has a name, e.g. “Name_cannot_be_null”
  2. It has a mutation action
  3. It has a validation part

These all can be treated as data for a data-driven test.
The test base class could contain a [Theory] with [MemberData] as its data source, and the data source could come from the inheritors.

This way, an inheritor test class can shrink to an even smaller size, specifying only the list of (name, mutation, validation) objects.

I will not be demonstrating this as e.g. the solution would be highly dependent on the given unit test framework (and so far we were mostly independent of it), but now that you got the idea of how it would work, you can implement it by yourself.

It is also possible to make the CreateValidator() method optional (virtual) by giving the ValidatorTestBase class a second type parameter:

public abstract class ValidatorTestBase<TModel, TValidator> 
    where TValidator : IValidator<TModel>, new()

This way, if the implementor has a validator with a default constructor, they won’t have to specify the way of validator creation.
I omitted this part in the example of the previous part because it requires a second type parameter which seems a bit noisy to me, but if you can live with it, feel free to use it.

]]>
Rider: how to setup non-English spell checking2022-02-18T06:00:00+00:002022-02-18T06:00:00+00:00https://arphox.github.io/2022/02/18/rider-hunspellIntro

If you are working on code that has non-English comments, it is useful to have spell checking for that given language.
In my case, the language is Hungarian, and the IDE is JetBrains Rider.
Today we find out how we can set it up.

Overview

The tool (plugin) we are going to use has its own dictionary format so we will need a specific kind of dictionary file.
The process will include installing the plugin we need, downloading the dictionary for the language we want, and add that language as a custom dictionary in Rider.

Steps

  1. Install the Hunspell plugin (1)
  2. Download the Hungarian dictionary from here, put the whole directory to some (permanent) space on your drive. (2,3)
  3. Go to Settings -> Editor -> Spelling in Rider.
  4. At Custom dictionaries, click the plus (+) button.
  5. Select the index.dic file in the directory you downloaded the dictionary to.
  6. Click Save.
  7. (optional) Restart Rider (4)

Notes

  • (1) It is called Hunspell because originally it has been developed for Hungarian but it has dictionaries to support many languages.
  • (2) You don’t specifically need files from that repo; you can use Google to download the dictionary you want but be careful to download them in Hunspell format.
  • (3) Note that if you delete or move the directory where the dictionary is, it will probably break the plugin as it won’t reach the dictionary.
  • (4) After clicking Save Hungarian spell checking started to work however English got buggy, but after an IDE restart it got fixed so I recommend restarting the IDE just to be sure.

Non-Hungarian

This process should work with other languages too if you select a different dictionary file at Step 2.
For example I tried Spanish too and it worked.

]]>
How to remove password from pdf file*2021-12-02T08:01:26+00:002021-12-02T08:01:26+00:00https://arphox.github.io/2021/12/02/remove-password-from-pdf* given you have the password

Intro

Sometimes we get a password-protected PDF file. We know the password, it’s just inconvenient to always enter it when you want to open it, so we may want to remove the password protection.

The easy way

Your favorite PDF viewer (or editor) may be able to remove the password, so if you only need to decrypt only one pdf, start there!

If you need a recommendation on a PDF viewer, I recommend PDF-XChange Viewer, it’s fast and free.
If you want to do that using PDF-XChange Viewer then you can do it by: (Open pdf), File -> Document Properties -> Security (category) -> change Security Method to “No Security” -> OK -> Close dialog -> Save file

However, if you need to decrypt many files at once, keep reading.

The automated way - QPDF

You can remove password using a command-line tool, QPDF.
Don’t worry, no install is required.

Note: We will use Windows 10, but QPDF should be available on other systems too.

Get QPDF

First, download it then extract it somewhere.
For example, I extracted it to: d:\demo\qpdf-10.4.0\.

Usage

Open the command line.

Enter: Q --password=PW --decrypt DC NEW
where:

  • Q: path to qpdf.exe
  • PW: the password of the file
  • DC: the path of the pdf file to decrypt
  • NEW: path to save the output file

So for example, in my case: D:\demo\qpdf-10.4.0\bin\qpdf.exe --password="asd" --decrypt "D:\demo\my_encrypted_pdf.pdf" "D:\demo\decrypted.pdf"

Result: I can find my decrypted (password removed) pdf at "D:\demo\decrypted.pdf".

Decrypt all files in directory

For advanced users: you can use this Powershell-script to decrypt all files in a directory:

# $pdfsDirPath: path to directory containing pdfs to decrypt
#   - decrypted pdfs are put to the \decrypted subfolder here
# $qpdfPath: path to qpdf.exe
# $pdfPassword: password of the pdf files

$pdfsDirPath = "d:\demo\script\pdfs-to-decrypt\"
$qpdfPath = "D:\demo\script\qpdf-10.4.0\bin\qpdf.exe"
$pdfPassword = "asd"

$decryptedPdfDirPath = [System.IO.Path]::Combine($pdfsDirPath, 'decrypted')
[System.IO.Directory]::CreateDirectory($decryptedPdfDirPath)

Get-ChildItem $pdfsDirPath |
ForEach-Object {
    $extension = [System.IO.Path]::GetExtension($_.FullName)
    if ($extension -ne ".pdf") {
        Write-Host Skipping non-pdf file or directory: $_.FullName
        return
    }
    $decryptedPdfPath = [System.IO.Path]::Combine($decryptedPdfDirPath, $_.Name)
    & $qpdfPath --password=$pdfPassword --decrypt $_.FullName $decryptedPdfPath
    Write-Output Decrypted $decryptedPdfPath
}

Troubleshoot

  • If something does not work, maybe try the version I used, which is 10.4.0, or just read the error description 😃
]]>