<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Benjamin Steenhoek</title>
    <description>The latest articles on DEV Community by Benjamin Steenhoek (@benjis).</description>
    <link>https://dev.to/benjis</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F824987%2F93d3dc43-fe55-478a-9cc1-9193adf61b1c.jpg</url>
      <title>DEV Community: Benjamin Steenhoek</title>
      <link>https://dev.to/benjis</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/benjis"/>
    <language>en</language>
    <item>
      <title>Programming problem: Gematria</title>
      <dc:creator>Benjamin Steenhoek</dc:creator>
      <pubDate>Fri, 13 May 2022 07:00:00 +0000</pubDate>
      <link>https://dev.to/benjis/programming-problem-gematria-1fb4</link>
      <guid>https://dev.to/benjis/programming-problem-gematria-1fb4</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vOCSivdU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on60ujzrueuoank5devr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vOCSivdU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/on60ujzrueuoank5devr.jpg" alt="Torah" width="880" height="300"&gt;&lt;/a&gt;&lt;br&gt;
Photo by &lt;a href="https://unsplash.com/@tannermardis?utm_medium=referral&amp;amp;utm_campaign=photographer-credit&amp;amp;utm_content=creditBadge"&gt;Tanner Mardis&lt;/a&gt; on Unsplash&lt;/p&gt;

&lt;p&gt;I’ve recently been studying history in the Bible by following along with the phenomenal podcast of the same name, &lt;a href="https://www.historyinthebible.com/"&gt;History in the Bible by Garry Stevens&lt;/a&gt;. As part of his series, I learned about &lt;a href="https://en.wikipedia.org/wiki/Gematria"&gt;gematria&lt;/a&gt;, which is the ancient practice of assigning a number to a name based on the letters in the name.&lt;/p&gt;

&lt;p&gt;The use of gematria was/is present in many cultures, including ancient Greek, Hebrew, Arabic, and English. Some historians hypothesize that the number of the beast (666) came about from the numeric value, of the Greek name “Nero Caesar”. I’m not an expert on that, but I do think it’s a fun little game to convert different words into their numeric value, especially if the value coincides with some related tidbit.&lt;/p&gt;

&lt;p&gt;Let’s explore how gematria works, frame it as a programming problem/exercise, and check out some solutions - plus, we will learn some programming along the way.&lt;/p&gt;
&lt;h2&gt;
  
  
  How gematria works
&lt;/h2&gt;

&lt;p&gt;First, we map each Hebrew letter to a numeric value:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Decimal&lt;/th&gt;
&lt;th&gt;1&lt;/th&gt;
&lt;th&gt;2&lt;/th&gt;
&lt;th&gt;3&lt;/th&gt;
&lt;th&gt;4&lt;/th&gt;
&lt;th&gt;5&lt;/th&gt;
&lt;th&gt;6&lt;/th&gt;
&lt;th&gt;7&lt;/th&gt;
&lt;th&gt;8&lt;/th&gt;
&lt;th&gt;9&lt;/th&gt;
&lt;th&gt;10&lt;/th&gt;
&lt;th&gt;20&lt;/th&gt;
&lt;th&gt;20&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hebrew&lt;/td&gt;
&lt;td&gt;Aleph&lt;/td&gt;
&lt;td&gt;Bet&lt;/td&gt;
&lt;td&gt;Gimel&lt;/td&gt;
&lt;td&gt;Dalet&lt;/td&gt;
&lt;td&gt;He&lt;/td&gt;
&lt;td&gt;Vav&lt;/td&gt;
&lt;td&gt;Zayin&lt;/td&gt;
&lt;td&gt;Het&lt;/td&gt;
&lt;td&gt;Tet&lt;/td&gt;
&lt;td&gt;Yod&lt;/td&gt;
&lt;td&gt;Kaf&lt;/td&gt;
&lt;td&gt;Kaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glyph&lt;/td&gt;
&lt;td&gt;א&lt;/td&gt;
&lt;td&gt;ב&lt;/td&gt;
&lt;td&gt;ג&lt;/td&gt;
&lt;td&gt;ד&lt;/td&gt;
&lt;td&gt;ה&lt;/td&gt;
&lt;td&gt;ו&lt;/td&gt;
&lt;td&gt;ז&lt;/td&gt;
&lt;td&gt;ח&lt;/td&gt;
&lt;td&gt;ט&lt;/td&gt;
&lt;td&gt;י&lt;/td&gt;
&lt;td&gt;כ&lt;/td&gt;
&lt;td&gt;כ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Decimal&lt;/th&gt;
&lt;th&gt;30&lt;/th&gt;
&lt;th&gt;40&lt;/th&gt;
&lt;th&gt;50&lt;/th&gt;
&lt;th&gt;60&lt;/th&gt;
&lt;th&gt;70&lt;/th&gt;
&lt;th&gt;80&lt;/th&gt;
&lt;th&gt;90&lt;/th&gt;
&lt;th&gt;100&lt;/th&gt;
&lt;th&gt;200&lt;/th&gt;
&lt;th&gt;300&lt;/th&gt;
&lt;th&gt;400&lt;/th&gt;
&lt;th&gt;20&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hebrew&lt;/td&gt;
&lt;td&gt;Lamed&lt;/td&gt;
&lt;td&gt;Mem&lt;/td&gt;
&lt;td&gt;Nun&lt;/td&gt;
&lt;td&gt;Samekh&lt;/td&gt;
&lt;td&gt;Ayin&lt;/td&gt;
&lt;td&gt;Pe&lt;/td&gt;
&lt;td&gt;Tsadi&lt;/td&gt;
&lt;td&gt;Kof&lt;/td&gt;
&lt;td&gt;Resh&lt;/td&gt;
&lt;td&gt;Shin&lt;/td&gt;
&lt;td&gt;Tav&lt;/td&gt;
&lt;td&gt;Kaf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glyph&lt;/td&gt;
&lt;td&gt;ל&lt;/td&gt;
&lt;td&gt;מ&lt;/td&gt;
&lt;td&gt;נ&lt;/td&gt;
&lt;td&gt;ס&lt;/td&gt;
&lt;td&gt;ע&lt;/td&gt;
&lt;td&gt;פ&lt;/td&gt;
&lt;td&gt;צ&lt;/td&gt;
&lt;td&gt;ק&lt;/td&gt;
&lt;td&gt;ר&lt;/td&gt;
&lt;td&gt;ש&lt;/td&gt;
&lt;td&gt;ת&lt;/td&gt;
&lt;td&gt;כ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Then, we add the values in the word together.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;ח&lt;/th&gt;
&lt;th&gt;+&lt;/th&gt;
&lt;th&gt;י&lt;/th&gt;
&lt;th&gt;=&lt;/th&gt;
&lt;th&gt;חי&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;18&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Here are some cool examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The value of &lt;em&gt;alive&lt;/em&gt; (חי) is 18, prompting some people to donate money in multiples of 18.&lt;/li&gt;
&lt;li&gt;The value of &lt;em&gt;[Ha-]Satan&lt;/em&gt; (הַשָּׂטָן) is 364, leading to the saying that out of the 365 days in the year, &lt;em&gt;Satan&lt;/em&gt; has 364 days to prosecute. Wow, he earned that 1-day vacation!&lt;/li&gt;
&lt;li&gt;The value of &lt;em&gt;snake&lt;/em&gt; when transliterated from Greek (דרקון) is 360, which is probably the reason for a peculiar passage in 3 Baruch: &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;And this is Hades, which itself also closely resembles him, in that it also drinks about a cubit from 7 the sea, which does not sink at all. Baruch said, And how (does this happen)? And the angel said, Hearken, the Lord God made three hundred and sixty rivers, of which the chief of 8 all are Alphias, Abyrus, and the Gericus; and because of these the sea does not sink.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;The value of my name, &lt;em&gt;Benjamin&lt;/em&gt; (בִּנְיָמִין), is 162.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Mispar Gadol
&lt;/h3&gt;

&lt;p&gt;There are several different cipher algorithms which are used, some from antiquity and some more modern. One example is &lt;em&gt;Mispar Gadol&lt;/em&gt;, where the final forms of certain Hebrew characters are given large values (when certain characters are used at the end of a word, they are written with a final form which is different from their usual form). This results in a different numeric value for one word, depending on whether you’re using the traditional cipher algorithm or Mispar Gadol.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Decimal&lt;/th&gt;
&lt;th&gt;500&lt;/th&gt;
&lt;th&gt;600&lt;/th&gt;
&lt;th&gt;700&lt;/th&gt;
&lt;th&gt;800&lt;/th&gt;
&lt;th&gt;900&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Hebrew&lt;/td&gt;
&lt;td&gt;Kaf (final)&lt;/td&gt;
&lt;td&gt;Mem (final)&lt;/td&gt;
&lt;td&gt;Nun (final)&lt;/td&gt;
&lt;td&gt;Pe (final)&lt;/td&gt;
&lt;td&gt;Tsadi (final)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Glyph&lt;/td&gt;
&lt;td&gt;ך&lt;/td&gt;
&lt;td&gt;ם&lt;/td&gt;
&lt;td&gt;ן&lt;/td&gt;
&lt;td&gt;ף&lt;/td&gt;
&lt;td&gt;ץ&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I thought this would be an interesting beginner-level programming problem, seeing as the results can be pretty interesting or culturally significant, and the different ciphers. Let’s state the problem!&lt;/p&gt;
&lt;h2&gt;
  
  
  The gematria programming problem
&lt;/h2&gt;

&lt;p&gt;Given a sequence of &lt;code&gt;n&lt;/code&gt; Hebrew letters &lt;code&gt;&amp;lt;letter 1&amp;gt; &amp;lt;letter 2&amp;gt; ... &amp;lt;letter n&amp;gt;&lt;/code&gt;, print the numeric value of those letters according to the gematria cipher. The inputs are given with romanized ASCII characters for simplicity.&lt;/p&gt;

&lt;p&gt;The code for this exercise can be found here: &lt;a href="https://github.com/bstee615/gematria"&gt;https://github.com/bstee615/gematria&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Example 1: alive 

&lt;ul&gt;
&lt;li&gt;Input: &lt;code&gt;het yod&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Output: 18&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Example 2: snake 

&lt;ul&gt;
&lt;li&gt;Input: &lt;code&gt;dalet resh kof vav nun&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Output: 360&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Template code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# this maps from Hebrew characters to their corresponding values.
&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"aleph"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"bet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"gimel"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"dalet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"he"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"vav"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"zayin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"het"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"tet"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"yod"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"kaf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"lamed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"mem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;40&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"nun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"samekh"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"ayin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"pe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"tsadi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"kof"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"resh"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"shin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"tav"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# fill in your solution here
&lt;/span&gt;    &lt;span class="k"&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Solutions for students
&lt;/h2&gt;

&lt;p&gt;This problem can be solved by looping through the letters and mapping each letter to a character, then summing the results. I’ll walk through a few different variants of the solution in order to illustrate its didactic function.&lt;/p&gt;

&lt;h3&gt;
  
  
  Simple solution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Calculate the gematria for a word using a loop"""&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  List comprehensions
&lt;/h3&gt;

&lt;p&gt;This problem can be used to introduce simple comprehensions to replace the loop. Python programmers should learn to use this construct because it allows natural and understandable expression when used correctly, as you can see here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Calculate the gematria for a word using a comprehension"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what the output looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Standard encoding using solve_comprehension:
dalet resh kof vav nun 360
he shin tet nun 364
het yod 18
bet nun yod mem yod nun 162
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  More fun with Mispar Gadol
&lt;/h3&gt;

&lt;p&gt;Finally, gematria can be used to introduce the usage of the &lt;code&gt;enumerate&lt;/code&gt; method and &lt;code&gt;Dictionary.get&lt;/code&gt; method with a default value in order to implement the Mispar Gadol variant.&lt;code&gt;get&lt;/code&gt; and &lt;code&gt;enumerate&lt;/code&gt; are also important for the same reason - they allows natural and understandable expression when used correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# this maps from the final form of these characters to their corresponding values.
&lt;/span&gt;&lt;span class="n"&gt;final_mapping&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s"&gt;"kaf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"mem"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;600&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"nun"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;700&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"pe"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;800&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s"&gt;"tsadi"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;900&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;solve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="s"&gt;"""Calculate the Mispar Gadol gematria for a word using the dictionary get() method with default"""&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="n"&gt;final_mapping&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;# get final_mapping[c] if c is a key, otherwise get mapping[c]...
&lt;/span&gt;      &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="c1"&gt;# ...if this character is the final form
&lt;/span&gt;      &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="n"&gt;mapping&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;enumerate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Mispar gadol encoding using solve_mg:
dalet resh kof vav nun 1010
he shin tet nun 1014
het yod 18
bet nun yod mem yod nun 812
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;I hope that you enjoyed learning about this cool gematria cipher. I find it interesting to think that the name you’re given when you’re born also gives you a special number. Maybe you will pair up with a person who has the same number. Who knows?&lt;/p&gt;

&lt;p&gt;Feel free to message me with the numeric value of your name, as well as your mother’s maiden name and the numeric value of your credit card. 😁 joking. But seriously, I’d be glad to hear if you thought this programming problem is interesting or have a cool number of your own.&lt;/p&gt;

</description>
      <category>programmingproblems</category>
      <category>python</category>
      <category>cryptography</category>
    </item>
    <item>
      <title>No pain no gain? Comparing 3 program analysis frameworks for C</title>
      <dc:creator>Benjamin Steenhoek</dc:creator>
      <pubDate>Thu, 03 Mar 2022 20:54:15 +0000</pubDate>
      <link>https://dev.to/benjis/no-pain-no-gain-comparing-3-program-analysis-frameworks-for-c-5ij</link>
      <guid>https://dev.to/benjis/no-pain-no-gain-comparing-3-program-analysis-frameworks-for-c-5ij</guid>
      <description>&lt;p&gt;&lt;em&gt;Original post: &lt;a href="https://benjijang.com/posts/2022/03/no-pain-no-gain/"&gt;https://benjijang.com/posts/2022/03/no-pain-no-gain/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Program analysis methods often represent programs as graphs. These graphs should be automatically generated from the source code. There are many tools that have been implemented to do this, but they are often painful to set up. In this post, I will compare 3 program analysis frameworks which I have used to generate graph representations of C programs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; More powerful frameworks are more difficult to set up because they require compiler information or expose complex APIs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SrcML is great if all you need is the AST and you don't need 100% precision.&lt;/li&gt;
&lt;li&gt;Joern is great if you need the CFG or PDG for a large set of programs, and are OK with potentially parsing some programs incorrectly.&lt;/li&gt;
&lt;li&gt;LLVM is great if you want a rock-solid analysis and want to leverage complex program analysis passes used in the Clang compiler, and you can provide compiler information.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QM6wUPQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkhrdd6e0293r9ledy0y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QM6wUPQ1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dkhrdd6e0293r9ledy0y.png" width="512" height="222"&gt;&lt;/a&gt;&lt;br&gt;No pain ⇒ no gain. More pain ⇒ more gain???&lt;br&gt;
(source: &lt;a href="https://www.dreamstime.com/stock-illustration-gradual-development-muscle-building-weakling-to-steep-pitching-funny-cartoon-character-vector-illustration-isolated-image48375937"&gt;kharlamova&lt;/a&gt;)&lt;br&gt;

  &lt;/p&gt;

&lt;h2&gt;
  
  
  Control flow what-now?
&lt;/h2&gt;

&lt;p&gt;Different types of graphs are used for different analyses, depending on what information is needed [0]:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Abstract Syntax Tree (AST): A tree representation of the tokens in a program which abstracts out details like parentheses, whitespace, and separators.&lt;/li&gt;
&lt;li&gt;Control Flow Graph (CFG): A graph representation where each node is a statement and each edge is a transition in control flow.&lt;/li&gt;
&lt;li&gt;Program Dependence Graph (PDG): A graph representation where each node is a statement and each edge is a control or data dependency. A variable is dependent on a statement if that statement affects the value of the variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I chose to study the relative benefits of 3 popular program analysis frameworks that I have used in my own research:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.srcml.org/"&gt;SrcML: an infrastructure for the exploration, analysis, and manipulation of source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://joern.io/"&gt;Joern: The Bug Hunter's Workbench&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://llvm.org/"&gt;LLVM: a collection of modular and reusable compiler and toolchain technologies&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I evaluated the frameworks based on 3 criteria which we care about for any program analysis task.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Speed: how fast is the framework?&lt;/li&gt;
&lt;li&gt;Precision: how precise is the resulting CFG?&lt;/li&gt;
&lt;li&gt;Ease of use: how much effort does it take to use the framework, esp. on a large set of programs?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of these graph representations can be automatically generated from C source code, though the task is sometimes challenging.&lt;/p&gt;

&lt;h2&gt;
  
  
  Challenges parsing C code
&lt;/h2&gt;

&lt;p&gt;C programs are difficult to parse because the preprocessor allows arbitrary text substitution [1]. If preprocessor macros aren't defined, the parser can misinterpret the context of a certain chunk of code and parse it totally incorrectly. I call this &lt;em&gt;imprecision&lt;/em&gt; in my evaluation of the 3 frameworks.&lt;/p&gt;

&lt;p&gt;C programs also require compiler information such as types and functions defined in header files in order to parse correctly [2]. These header files can be scattered all across the machine, and the standard library headers are are in different locations in different OS or distributions. The compiler information is usually passed to the parser by way of compiler flags such as &lt;code&gt;-I&lt;/code&gt; or &lt;code&gt;-D&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EqNSr5Xw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yejf6uwhdglzftain6u9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EqNSr5Xw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yejf6uwhdglzftain6u9.png" width="512" height="274"&gt;&lt;/a&gt;&lt;br&gt;Relative benefits of SrcML, Joern, and LLVM.&lt;br&gt;
(source: original)&lt;br&gt;

  &lt;/p&gt;

&lt;h2&gt;
  
  
  SrcML
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.srcml.org/"&gt;SrcML&lt;/a&gt; is an XML format for source code.&lt;br&gt;
It provides the AST in a language-independent format. It also preserves all characters, including whitespace, comments, and preprocessor macros.&lt;/p&gt;

&lt;p&gt;SrcML can parse code with missing includes and libraries, which makes it a great fit for large-scale program analysis (on the order of millions of programs). However, this also means that the AST can be incorrect sometimes. The problem is worsened in the presence of preprocessor macros. The SrcML parser uses a set of heuristics to deal with these challenges, but it sometimes results in an incorrect AST.&lt;/p&gt;

&lt;p&gt;The SrcML authors claim it is faster than a compiler (over 25KLOC/sec) [3]. I have observed that it does run very fast, and additionally can do all its processing in memory due to the fact that it outputs XML as text.&lt;/p&gt;

&lt;p&gt;SrcML provides the AST but not the CFG or PDG. In order to obtain the CFG, then, we would have to implement an algorithm to generate the CFG based on the AST. Some projects have done this as part of their implementation (notably &lt;a href="https://github.com/srcML/srcSlice"&gt;srcSlice&lt;/a&gt; and &lt;a href="https://github.com/srcML/srcPtr"&gt;srcPtr&lt;/a&gt;), but I found it difficult to adapt these implementations for other uses.&lt;/p&gt;

&lt;p&gt;The SrcML format is language-independent, so theoretically, you could write an analysis based on the XML format and apply it to all the languages supported (currently C, C++, C#, and Java).&lt;/p&gt;

&lt;p&gt;Interestingly, SrcML is &lt;em&gt;reversible&lt;/em&gt;, meaning a user can parse code into XML, edit the XML, then un-parse the XML back into code while preserving the edits. This allows some cool editing functionality, and I found it easier in some cases than editing the raw source code because I can locate the symbols I want to edit by traversing the XML tree.&lt;/p&gt;

&lt;p&gt;The SrcML team was pretty responsive in my queries about their framework.&lt;/p&gt;


&lt;h2&gt;
  
  
  Joern
&lt;/h2&gt;



&lt;p&gt;&lt;a href="https://joern.io/"&gt;Joern&lt;/a&gt; is a workbench which parses C/C++ code and generates a Code Property Graph (CPG). The CPG is a combination of AST, CFG, and PDG into one big graph, and it exposes information sufficient to perform a wide range of analyses. The main interface to the tool is a command-line interpreter which allows users to write custom queries in a DSL based on Scala.&lt;/p&gt;

&lt;p&gt;Joern does not require compiler information, but uses a fuzzy parsing method known as &lt;em&gt;island grammars&lt;/em&gt; to parse the code as best as it can.&lt;/p&gt;

&lt;p&gt;I found that the Joern implementation runs much slower than both SrcML and LLVM. This may be because of the choice of runtime platform: SrcML and LLVM are built with C++ and have narrow functionality, while Joern is built with Scala and is highly customizable/scriptable.&lt;/p&gt;

&lt;p&gt;Multiple languages are supported: C/C++, x86/64 assembly, JVM, LLVM Bitcode, and Javascript. I've only tried C/C++, and these are the only languages marked as &lt;em&gt;high&lt;/em&gt; maturity on their &lt;a href="https://docs.joern.io/home#supported-languages"&gt;doc page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Joern includes great utilities for analysis, but any modifications to the code must be manually pasted together. There is no support for rewriting or transformation.&lt;/p&gt;

&lt;p&gt;The ShiftLeft team is very active in developing Joern, and they are helpful to users of their framework.&lt;/p&gt;
&lt;h2&gt;
  
  
  LLVM
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://llvm.org/"&gt;LLVM&lt;/a&gt; is the granddaddy of all program analysis frameworks. It is a mature collection of tools designed for compiler development.&lt;/p&gt;

&lt;p&gt;LLVM is the foundation of the Clang compiler, Clang Static Analyzer (CSA), klee, and many other well-known tools.&lt;br&gt;
Because it's used in so many popular tools, it is optimized to be blazing fast.&lt;br&gt;
LLVM exposes APIs for AST, CFG, and PDG information as well as &lt;a href="https://llvm.org/docs/Passes.html"&gt;a whole host of other analyses&lt;/a&gt;.&lt;br&gt;
Basically, any information available to the compiler is available to the developer of an LLVM tool. As well, the information is 100% precise, as a compiler cannot tolerate incorrect information.&lt;/p&gt;

&lt;p&gt;This power comes with a price - LLVM requires all types to be defined in order to parse the code correctly. Due to C's ambiguous grammar, if a type is not defined, then the compiler cannot tell the difference between a function definition and a variable definition, leading to errors in parsing (cite). If some definitions are missing, LLVM can produce a broken AST with large sections missing.&lt;/p&gt;

&lt;p&gt;Usually, this information is provided by giving LLVM a set of compiler flags that would be used to compile the program. It can be difficult to get these flags if you want to analyze a lot of programs, since the flags are platform- and configuration-dependent.&lt;br&gt;
This can introduce a lot of manual effort to obtain these flags, which can render LLVM infeasible for analyzing large-scale program datasets.&lt;/p&gt;

&lt;p&gt;LLVM's analysis functionality only processes C/C++ at the source level. Additional utilities are available for LLVM IR, which is a low-level SSA assembly language which many other languages target.&lt;/p&gt;

&lt;p&gt;LLVM provides the &lt;a href="https://clang.llvm.org/doxygen/classclang_1_1Rewriter.html"&gt;Rewriter API&lt;/a&gt; for rewriting source code. I found these utilities to be very convenient in most cases, although in some cases when the location I want to rewrite was not exposed by the Clang AST, it was difficult to work around the rewriter API.&lt;/p&gt;

&lt;p&gt;Finally, I found that the LLVM C++ API &lt;a href="https://clang.llvm.org/docs/LibTooling.html"&gt;LibTooling&lt;/a&gt; can be intuitive and comfortable at times, but often the details are very complex and there are a lot of footguns.&lt;br&gt;
I got better at using it from experience, but it still takes me a while to figure out &lt;a href="https://clang.llvm.org/docs/LibASTMatchersReference.html"&gt;which ASTMatcher I should use&lt;/a&gt; or &lt;a href="https://clang.llvm.org/docs/RefactoringEngine.html"&gt;whether to use the refactoring engine&lt;/a&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Benchmark analysis
&lt;/h2&gt;

&lt;p&gt;I implemented a simple refactoring tool with each framework in order to evaluate the speed of each tool.&lt;br&gt;
The refactoring tool exchanges a &lt;code&gt;for&lt;/code&gt; statement with a &lt;code&gt;while&lt;/code&gt; statement. This can be done with AST only, though control-flow information is necessary in order to handle early &lt;code&gt;break&lt;/code&gt;, &lt;code&gt;cont&lt;br&gt;
inue&lt;/code&gt;, or &lt;code&gt;return&lt;/code&gt;. You can access the prototype's source code here: &lt;a href="https://github.com/bstee615/pa_framework_examples"&gt;https://github.com/bstee615/pa_framework_examples&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is an example of the tool at work. When this program is input:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then this program should be the output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I measured the runtime of my prototype tool in seconds on the example program, averaged over 5 runs.&lt;br&gt;
The results are shown below. Format: Average ± std. deviation.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;LLVM&lt;/th&gt;
&lt;th&gt;Joern&lt;/th&gt;
&lt;th&gt;SrcML&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.0230s ± 0.0034s&lt;/td&gt;
&lt;td&gt;6.2906s ± 0.0034s&lt;/td&gt;
&lt;td&gt;0.0702s ± 0.0088s&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This evaluation shows the difference in startup times between the frameworks. In my research I have found that the startup time is a pretty large consideration, and the size of the program has a relatively small effect on the framework's performance.&lt;/p&gt;

&lt;p&gt;LLVM and SrcML are pretty similar in performance for all practical matters. Notably, I used Python to invoke SrcML and parse the output XML. It may be slightly faster if I wrote it in C++ and linked with the SrcML library.&lt;/p&gt;

&lt;p&gt;Joern was the slowest by far. This may be due to the overhead of starting up the Scala VM and Joern's interpreter.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--50ixXac3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/varxp2ea4y9zfxbjgrd5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--50ixXac3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/varxp2ea4y9zfxbjgrd5.png" width="880" height="573"&gt;&lt;/a&gt;&lt;br&gt;Frameworks are multi-dimensional, not just lightweight/heavyweight.&lt;br&gt;
(source: &lt;a href="https://www.self.com/story/guide-to-navigating-free-weights-at-the-gym"&gt;Morgan Johnson&lt;/a&gt;)&lt;br&gt;

  &lt;/p&gt;

&lt;p&gt;Each of these frameworks has its sweet spot in program analysis. In reality, analyzing real-world programs is difficult. There are many choices with different dimensions of pain/pleasure. I compared speed on a small example to highlight the differences between the frameworks. I suggest you do your own research into these 3 frameworks to figure out which one fits your application best. Most importantly, don't be dogmatic about using one approach over another - for example, supposing you are used to LLVM giving you compiler-level precision in your analyses, you may benefit from switching to Joern in order to speed up your development cycle.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;p&gt;[0] F. Yamaguchi, N. Golde, D. Arp and K. Rieck, "Modeling and Discovering Vulnerabilities with Code Property Graphs," 2014 IEEE Symposium on Security and Privacy, 2014, pp. 590-604, DOI: &lt;a href="https://doi.org/10.1109/SP.2014.44"&gt;https://doi.org/10.1109/SP.2014.44&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[1] Alejandra Garrido and Ralph Johnson. 2002. Challenges of refactoring C programs. In Proceedings of the International Workshop on Principles of Software Evolution (IWPSE '02). Association for Computing Machinery, New York, NY, USA, 6–14. DOI:&lt;a href="https://doi.org/10.1145/512035.512039"&gt;https://doi.org/10.1145/512035.512039&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] Bendersky, E. (2007, Nov). The context sensitivity of C's grammar. Eli Benderskys website ATOM. Retrieved March 3, 2022, from &lt;a href="https://web.archive.org/web/20210713114717/https://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar"&gt;https://web.archive.org/web/20210713114717/https://eli.thegreenplace.net/2007/11/24/the-context-sensitivity-of-cs-grammar&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;[3] M. L. Collard, M. J. Decker and J. I. Maletic, "srcML: An Infrastructure for the Exploration, Analysis, and Manipulation of Source Code: A Tool Demonstration," 2013 IEEE International Conference on Software Maintenance, 2013, pp. 516-519, DOI: &lt;a href="https://doi.org/10.1109/ICSM.2013.85"&gt;https://doi.org/10.1109/ICSM.2013.85&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>cpp</category>
      <category>computerscience</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
