Miscellaneous - Random knowledge that won't fit any other category

mail

COW🐮

mail

Perl regular expressions

The manuals

Reference

\K
causes the regex engine to "keep" (hold) everything it had matched prior to the \K and not include it in $&
  • the documentation says both are equivalent :
    echo foobar | perl -pe 's/(foo)bar/$1/g;'
    echo foobar | perl -pe 's/foo\Kbar//g;'	but this one is much more efficient
    and return :
    foo
  • I still have to figure how the regex is processed :
    
    echo foobar | perl -pe 's/foo\Kbar//g;'
    foo
    
    - get the 'foobar' input string
    - read the 'foo\Kbar' regex as the "search" part of the 's///' command
    - because of the \K, it "holds" (forgets ?) anything matched before : i.e. the 'foo' part
    - remains the 'bar' part
    - the 's///' command becomes : 's/bar//', i.e. "remove 'bar'"
    
    
    echo 'foobar' | grep -oP 'foo\Kbar'
    bar
    
    - looks like it does the opposite of the example above, but it's not ;-)
    - 'foo\Kbar' can be understood as "forget 'foo', keep 'bar'"
    - in the example above, this is provided as the "search" part of an 's///' command : replace 'bar' with nothing, i.e. keep 'foo'
    - in this example, it is what's happening : grep [options] ""forget 'foo', keep 'bar'"" : outputs 'bar'
    

Examples

Extract data from XML

Let's consider this snippet of XML :
<data>
	<key name="foo">
		<value>ga bu</value>
	</key>
	<key name="bar">
		<value>zo meu</value>
	</key>
</data>
from which I'd like to extract the highlighted values.
with sed :
cat << EOF | sed -r -e 's/</\n</g' -e 's/>/>\n/g' | sed -r '/(^[[:blank:]]*$|[<>])/ d'
<data>
	<key name="foo">
		<value>ga bu</value>
	</key>
	<key name="bar">
		<value>zo meu</value>
	</key>
</data>
EOF
ga bu
zo meu
with grep and Perl regular expressions :
cat << EOF | grep -oP '<value>\K[^<]+'
<data>
	<key name="foo">
		<value>ga bu</value>
	</key>
	<key name="bar">
		<value>zo meu</value>
	</key>
</data>
EOF
ga bu
zo meu
The magic here is that '<value>\K[^<]+' is interpreted as :
- focus on what comes after <value>
- match any sequence of characters until you find a <
mail

The ISO 8601 date and time expression format

ansible localhost -m setup
"ansible_facts": {
	...
	"ansible_date_time": {
		"date": "2023-10-25",
		"day": "25",
		"epoch": "1698217860",
		"hour": "09",
		"iso8601": "2023-10-25T07:11:00Z",
		"iso8601_basic": "20231025T091100124951",
		"iso8601_basic_short": "20231025T091100",
		"iso8601_micro": "2023-10-25T07:11:00.124951Z",
		"minute": "11",
		"month": "10",
		"second": "00",
		"time": "09:11:00",
		"tz": "CEST",
		"tz_offset": "+0200",
		"weekday": "Wednesday",
		"weekday_number": "3",
		"weeknumber": "43",
		"year": "2023"
		},
	...
	}

Details about the format

basic vs unspecified format
  • basic : has a minimal number of separators
  • unspecified (aka extended) format : has separators to enhance human readability
    • - between date values
    • : between time values
T between date and time values
serves as a delimiter between date and time when they are concatenated
Trailing Z
indicates that the time is in UTC

What's the difference between UTC and GMT ? (sources : stackoverflow.com, currentmillis.com)

GMT UTC
is a time zone a time standard
is based on astronomical observations atomic clocks
states 1 second is 1/86400 of a day, with
  • 1 day = time between noon and the next noon
  • noon = moment when the sun is at its peak above Greenwich
This implies that 1 second is not a constant because the Earth rotation is not perfectly regular.
the time it takes a caesium 133 atom to do something 9,192,631,770 times in a row
This never changes.

What about leap seconds ?

Since the Earth rotation is uneven (and globally slowing down), GMT seconds can be randomly "longer" that constant UTC seconds. To workaround this, 1 leap second (one at a time !) can be added to UTC so that UTC and GMT are never more than 0.9s apart.
  • Leap second adjustments will stop by/before 2035 because they cause problems where an uninterrupted flow of time is required : satellite navigation, software, telecommunication, trade and even space travel (sources : theguardian.com, timeanddate.com).
  • The difference between astronomical and atomic time will be allowed to grow to a larger value than one second.
    • this value is yet to be determined by scientists
    • so are the means to deal with it

Which one should I use ?

Though conceptually different, I have never seen a computer program where it wasn't OK to regard GMT and UTC as equivalent. They are never more than 1 second off from each other, and computer software very often does not distinguish.

(from the comments to this question)
mail

How to mark comments in code ?

Context Single line Multiple lines Notes
Starts with ... Until ... Starts with ... Until ...
ASP ' end of line
Awk # end of line source
Bash, MySQL query # end of line
C, PHP, Javascript // end of line /* */
CSS /* */ /* */
HTML <!-- --> <!-- -->
LATEX % end of line
MS-Dos Batch (.bat, .cmd) REM end of line
Oracle query -- end of line
PERL # end of line
=cut

=cut

Must include blank lines before and after the comment tag
Python # end of line
  • '''
  • """
  • '''
  • """
source
VBA, VBS ' end of line
YAML (.yml) # end of line
  • a comment can start anywhere on the line
  • no support for block comments
  • source
mail

ANSI escape sequences

ANSI escape sequences define functions that :
  • change display graphics
  • control cursor movement
  • reassign keys
They are made of a sequence of ASCII characters, the first two of which are the ASCII Escape character 27 (1Bh) and the left-bracket character [ (5Bh). The character(s) following the escape and left-bracket characters specify an alphanumeric code that controls a keyboard or display function.

Let's play with colors in a terminal (source) :

text color

ansiCode_start='\033['
ansiCode_stop='m'
black="${ansiCode_start}0;30${ansiCode_stop}"
red="${ansiCode_start}0;31${ansiCode_stop}"
green="${ansiCode_start}0;32${ansiCode_stop}"
orange="${ansiCode_start}0;33${ansiCode_stop}"
blue="${ansiCode_start}0;34${ansiCode_stop}"
purple="${ansiCode_start}0;35${ansiCode_stop}"
cyan="${ansiCode_start}0;36${ansiCode_stop}"
lightGray="${ansiCode_start}0;37${ansiCode_stop}"
darkGray="${ansiCode_start}1;30${ansiCode_stop}"
lightRed="${ansiCode_start}1;31${ansiCode_stop}"
lightGreen="${ansiCode_start}1;32${ansiCode_stop}"
yellow="${ansiCode_start}1;33${ansiCode_stop}"
lightBlue="${ansiCode_start}1;34${ansiCode_stop}"
lightPurple="${ansiCode_start}1;35${ansiCode_stop}"
lightCyan="${ansiCode_start}1;36${ansiCode_stop}"
white="${ansiCode_start}1;37${ansiCode_stop}"
noColor="${ansiCode_start}0${ansiCode_stop}"

printf "I ${red}<3${noColor} Linux\n"
echo -e "I ${red}<3${noColor} Linux"

for color in black red green orange blue purple cyan lightGray darkGray lightRed lightGreen yellow lightBlue lightPurple lightCyan white; do echo -e "${!color}${color}${noColor}"; done
The 0;.. colors are the regular ones whereas the 1;.. are the light colors. Names don't exactly match : "dark gray" is actually a "light black", and "white" is a "light light gray"

text decoration

echo -e "\033[0;31m___solid_________\033[0m"
echo -e "\033[1;31m___bold__________\033[0m"
echo -e "\033[2;31m___dark__________\033[0m"
echo -e "\033[3;31m___italic________\033[0m"
echo -e "\033[4;31m___underlined____\033[0m"
echo -e "\033[5;31m___blink slow____\033[0m"
echo -e "\033[6;31m___blink fast____\033[0m"
echo -e "\033[7;31m___reverse_______\033[0m"
echo -e "\033[8;31m___hide__________\033[0m"
echo -e "\033[9;31m___strikeout_____\033[0m"

background color

echo -e "\033[41m___on red______\033[0m \t \033[101m___on high intensity red______\033[0m"
echo -e "\033[42m___on green____\033[0m \t \033[102m___on high intensity green____\033[0m"
echo -e "\033[43m___on yellow___\033[0m \t \033[103m___on high intensity yellow___\033[0m"
echo -e "\033[44m___on blue_____\033[0m \t \033[104m___on high intensity blue_____\033[0m"

high intensity (i.e. same color than the "bright", but not "bold")

echo -e "\033[0;34m___solid_________________\033[0m"
echo -e "\033[1;34m___bold__________________\033[0m"
echo -e "\033[0;94m___high intensity________\033[0m"
echo -e "\033[1;94m___bold high intensity___\033[0m"

combinations

echo -e "\033[43m\033[1;31m___bright red on yellow_____\033[0m"
echo -e "\033[43m\033[5;31m___blinking red on yellow___\033[0m"
mail

How to plug a Suunto watch into a Debian host ?

Spoiler : you can't .

https://github.com/openambitproject/openambit


the device communication lib : libambit


http://www.movescount.com/fr/apps
==> http://www.movescount.com/fr/groups/group5135-Linux_User_Group
http://sourceforge.net/projects/openambit/ (source : http://forum.ubuntu-fr.org/viewtopic.php?id=1211421)
http://openambit.org/forums/topic/ubuntu-14-04/
==> DEBIAN : https://tracker.debian.org/pkg/openambit
http://openambit.org/forums/topic/ubuntu-14-04/#post-164
mail

How to swap 2 variables without using a 3rd variable ?

Method :

step x y
0 a b
1 = x0 - y0
= a - b
= y0
= b
2 = x1
= a - b
= x1 + y1
= a - b + b
= a
3 = y2 - x2
= a - (a - b)
= a - a + b
= b
= y2
= a

Try it :

x=123; y=456; echo "BEFORE : x=$x, y=$y"; x=$((x-y)); y=$((x+y)); x=$((y-x)); echo "AFTER : x=$x, y=$y"
mail

NetApp SnapShot

1. A snapshot is taken. 2. Changed data is written to a new block and the pointer is updated, but the snapshot pointer still points to the old block, giving you a live view of the data and an historical view. 3. Another snapshot is taken and you now have access to 3 generations of your data without taking up the disk space that 3 unique copies would require : live, snapshot 2 and snapshot 1 in order of age.
mail

How to type special characters ?

Character Windows Linux
¡ AltGr-!
¼ ALT + 172
½ ALT + 171
¾ ALT + 243
¿ AltGr-?
À ALT + 183
  • CAPS LOCK then type the lowercase é/è/ê/ç/whatever...

  • ALT Gr. - SHIFT - then type the é/è/ê/ç/whatever...
 ALT + 182
Ç ALT + 128
È ALT + 200
É ALT + 144
Ê ALT + 210
Ô ALT + 226
ñ AltGr-~, n AltGr-^, n
mail

Regular Expressions, a.k.a RegExp

Different kinds of regular expressions :

They mostly differ on matters of syntax, what they consider a "normal" character or a "special" one.

BRE vs ERE (source 1, 2, 3) :

The main difference is that, in basic regular expressions :
  • characters such as ?, +, {, |, ( and ) have no special meaning
  • they must be escaped with \ to become special
BRE ERE
literal ( ( \(
grouping character \( (

Are we using BRE or ERE ?

echo -e "a\nb\nc" | /bin/grep 'b+'
(nothing)					the + is not special : BRE

echo -e "a\nb\nc" | /bin/grep 'b\+'
b						the + has become "special" : ERE

echo -e "a\nb\nc" | /bin/grep -E 'b+'
b						we've explicitly requested ERE with grep -E
In these examples, we use /bin/grep instead of just grep to make sure we're calling the grep binary itself rather than any local alias.
[[ "foo" =~ ^f.o$ ]] && echo match || echo 'no match'
match								. matches a single character (o, ., )

[[ "foo" =~ ^f\.o$ ]] && echo match || echo 'no match'
no match							\. does NOT match any single character

[[ "f.o" =~ ^f\.o$ ]] && echo match || echo 'no match'
match								\. matches a ., showing that =~ uses ERE

Special characters :

Expression Matches Example Details
. any single character dot / point / period .
+ the preceding item (expression or character) repeated at least 1 time + sign
* the preceding item repeated 0 or more times asterisk *
| either what's on the left or what's on the right alternation |
? 2 usages :
  1. optional-mode : the preceding item repeated either 0 or 1 time (=it becomes optional)
  2. lazy-mode : forces minimal matching when an expression can match a longer string.
    To perform its "minimal" match, a "closing" character is expected after the ? to instruct where matching stops.
    This also works in Emacs .
^foo nothing before foo, ^ = beginning of string beginning of string
foo$ nothing after foo, $ = end of string end of string
[a-z], [A-Z], [0-9] any single character in the range a-z, A-Z, 0-9 character lists
[12345] or [1-5] any single character in the list : 1, 2, 3, 4, 5
[^A-Z] any single character NOT in the list : everything except capital letters
expression{n} expression repeated n times interval expressions
(expression) + \n "what was matched by the nth (expression)"
  • echo '123-abc-4567' | sed -r 's/^([0-9]+)-([a-z]+)-(.*)$/\3+\1+\2/'
    4567+123+abc
  • also works in the search part of a s/// command :
    echo 'apple banana coconut' | sed -r 's/(..)\1/X/g'
    apple bXa Xnut
alias (aka callback or back reference) used by sed and by Emacs (in replace regexp mode)
parenthesis have different meanings depending on the context (BRE vs ERE), Emacs requires escaping them : \( and \)
character classes
[:alpha:] alphabetic characters, same as A-Za-z
  • echo -e 'a\n1\nb\n2' | grep '[[:alpha:]]'
  • echo -e 'a\n1\nb\n2' | sed -n '/[[:alpha:]]/p'
Character classes are pre-defined lists of characters (i.e. [:digit:] translates into 0123456789). As such, they have to be enclosed between [ and ] brackets :
[:blank:] blank characters : space and tab
  • echo -e 'ab\na b\na\tb' | grep '[[:blank:]]'
  • echo -e 'ab\na b\na\tb' | sed -n '/[[:blank:]]/p'
regular expression extensions
\y awk
\b grep
Perl
sed
word boundary (because not all words are separated by space or blank characters)
  • echo -e 'foo\nfoo1\nfoo2' | awk '/foo\y/'
    foo
  • echo -e 'hello\nhelloworld' | grep -E 'hello\b'
    hello
  • echo 'hello, world' | perl -pe 's/.*?(.)\b/\1/g'
    o d
    Had to use perl for this example because sed is greedy (.* matches the longest string it can find). In this example, I wanted to print several matches from the same line (source)
\s whitespace characters : space and tab

Bash snippet to play with regular expressions :

wordList='t 1 t1 1t test test1 1test test+ +test test+1 1+test te-1-st'; regExp='([A-Za-z].*[0-9])|([0-9].*[A-Za-z])'; for word in $wordList; do echo $word | grep -E "$regExp" || { echo "$word : no match"; }; done
mail

y = ax + b

Getting a and b :

y = ax + b

y1 = ax1 + b
y2 = ax2 + b

b = y1 - ax1

y2 = ax2 + y1 - ax1
y2 = a(x2 - x1) + y1

a(x2 - x1) = y2 - y1

a = ( y2 - y1 ) / ( x2 - x1 )

y1 = ax1 + b

b = y1 - ax1

b = y1 - x1 * ( y2 - y1 ) / ( x2 - x1 )

Getting x such as y = n :

y = ax + b

ax + b = n
ax = n - b

x = ( n - b ) / a
mail

Behavioral techniques

Commitment

It is close to impossible to say "No" after you said "Yes" first. With this "Yes", you are committed to act according to the decision you just made.
  • Would you mind looking at my luggage just for a minute ? (Then stop a thief)
  • What time is it, please ? (...) Do you have a quarter, I need to make an important phone call ?

The freeze effect

People tend to stick to decisions they consider as theirs (even though that decision was made by a group, or suggested by previous assertions).
After making a decision, people tend to comply with their decisions, even though it appears they made a mistake. New facts are not considered as they should be : help making the opposite (and right !) decision.
"A decision is forever".

The sunk cost

This happens when you persist on a decision / strategy / plan on which you already and massively invested (time / money / effort), even though you can switch to more affordable / valuable / cost-effective solutions.
  • Even though the movie is bad, you watch it until the end because you PAID for it.
  • Drinking a bad wine just because it is a famous (and expensive) bottle.

Entrapment ( + escalation of commitment)

Somewhat similar to the sunk cost, this one means several rounds of investment (time / money / effort), rather than changing one's mind. This happens when you persist on the same original plan, even though it's becoming over-expensive and can't work anymore
Escaping such a trap can be done by :
  • deciding it with a "STOP" decision. But such traps work so well because of the freeze effect.
  • setting a stop threshold before entering such a trap : wait n minutes only, spend at most n €, ...
  • The bus is late. Miss a first taxi, believing the bus will arrive soon. Miss another taxi. No bus. No more taxi. Walk back home. Waiting + walking was longer than taking the 1st taxi, or walk without waiting.
  • The Vietnam war, for the USA.
mail

Breaking passwords

The basics

Here are methods to get others' password (aka methods people may use to get yours) :
  1. Just ask ! Sounds stupid, but this often works
    • between colleagues in a rush
    • before someone leaves for holidays
    • with the appropriate social engineering methods
  2. Guess !
    • Birthday date, kid's 1st name, pet name, car plate number, loved person nickname, favorite band / song / movie / football team / ice cream brand /
    • Consider the most famous passwords in the world : love, secret, god, password, 123456, qwerty, letmein, 123123, ... (list)
  3. Steal it !
    • It may be noted on a Post-it™ note under the keyboard
    • or stored in a passwords.xls on a USB key
    • You can even —subtly— ask your victim about his mother's maiden name / childhood pet name / favorite teacher's name... or any question used in a Lost password form
  4. Break it with a dictionary attack.
  5. Break it with a brute force attack.

Crackers

When it comes to crackers —skilled people with heavy machinery who break passwords— things are a little bit different : their target is not to break specifically YOUR password, but to break as many passwords as possible (the lowest hanging fruits first) from the dump they have.
Knowing where the DB dump comes from (website, company) is very informative :
  • the "subscribe" form / corporate rules list the passwords requirements
  • it gives a hint on the type of users : gender, age, education, business, interests, ...
  • it gives a hint on the lexical field users may pick words from

Their methods

Crackers obviously won't ask, try to guess or steal your password as said above (which is what people you physically know / meet may do). They'll try various methods, starting from the most efficient (as for the number of passwords they can break) to the most complex (source) :
  • brute-force on all 6-character passwords
  • hybrid attack by testing passwords made of a dictionary word + 2 characters (digits / "special"), then 3, ...
  • Markov chain attack : since passwords have "patterns" (like "string-digits", "uppercase-lowercase-digit", "string-special-string", ...) it is possible to reduce the number of values to test
  • mask attack : like brute-force but more specific, based on patterns. This allows breaking, for instance, Julia1984 : this is a name, starting with an uppercase letter and followed by a year. Here come common symbol substitutions : 0 for o, | for l, $ for s, ... (which is why P@$$w0rd is plain sh*t )
  • combinator attack : each word of a dictionary is appended to each word in a dictionary. This is an answer to the correct horse battery staple thing.

Last minute thoughts

  • No password is safe forever :
    • make it an habit of changing passwords before they become crackable (i.e. if a given password is assumed to take 2 years to be brute-forced, change it after 1 year : whenever it's cracked, you changed it already)
    • on the other hand, forcing users to change their password regularly leads to weaker passwords, because users tend to choose passwords that are easy to remember, which often ends in _01, _02, _03 passwords.
    A safer solution would be to urge users to pick strong passwords made by a dedicated generator and train them to password managers (like KeePassXC), and let them decide when to change passwords (I don't mean to refrain users from changing their passwords, but —once they have understood the need for truly strong passwords and use them with password managers— changing a strong password for another strong password adds little to the overall system security).
  • Patterns suck :
    • qeadzcwrsfxv1331 looks long and solid, but it's actually a keyboard pattern on a QWERTY keyboard. Crackers have methods to test these too.
    • when generating passwords, patterns and rules decrease security :
      • strength comes from randomness (and we —humans— suck at this) : let a computer do the job for you !
      • P@ssw0rd_1234! has uppercase + lowercase + special + digits + is 15 characters long, so it must be very strong, right ?
  • Use distinct passwords across sites : in a users database, your password is linked to your email address, and your email address is present in all sites you have an account on. If your password is discovered, it becomes very easy to gain access to your other accounts
  • Any string that was once someone's password may be in a cracker's personal dictionary :
    • momof3gr8kids (mom of 3 great kids) was broken thanks to momof3 and gr8kids (which were probably previously broken via brute-force).
    • So if your password is
      • the concatenation of strings anybody already used as password
      • any string someone might already have thought of as for a "strong" password (even LAwL!:'"Yo7vY2u=Z#ti4VbcK!5>@f!%W;_- would be weak if widely used)
      it's actually weak. Use a generator.
  • Making a password out of 7 random words from a "large" list is considered safe.
  • Know when a password is "strong enough" : if it takes forever to brute-force it, doubling its length won't require crackers to run their programs until infinity twice to break it : if somebody wants your password hard enough, they'll find a way
mail

Social Engineering

Methods

Here are described some techniques to get "what you want" from somebody not willing to give it to you (and even without asking !)
Goal Target people Method
Get admin rights on a workstation Helpdesk
  1. Wait for a moment at which helpdesk technicians can not spend too much time with you (at lunch time when most of them have already left the office or are not back yet, during an issue occurring somewhere else (server crash, virus attack), during holidays/epidemic, or anytime they're not numerous enough)
  2. Ask the technician to perform some operation for which he has to log onto the target workstation with admin rights
  3. Ask him to launch any operation taking some time to perform, like defragmenting an HDD.
  4. If he's busy enough, he won't have time to wait until the defragmentation is done, so he may tell you : "Just log out when it's finished and enjoy."
  5. That's it : you have admin rights on your machine. You can now create a local administrator account for future use.

Other Strategies

The F.U.D. strategy
  • Fear : Gather facts / data / statistics so that the target people sees everybody has something to fear, and that "feeling safe" is different from "being safe"
  • Uncertainty : Everything has an uncertain side, just because some facts are unknown to everybody, things don't always behave as expected, and the future is unknown until it happens.
  • Doubt : Make the target people doubt about what they know (or think they know). Show them their understanding has (or can have) failures.
Changing one's mind
Statistically, when people make a decision which appears to be wrong afterwards, they often stick to their initial decision anyway. It seems that admitting one's made a mistake is more difficult than persevere in a wrong way. This works even better when occurring in public.
The "Tell a friend" strategy
Good friends are known to share secrets. Let's imagine you have something "hard" to say to Alice but you have no idea on how to let her know without hurting her feelings. Well, just tell it to Bob, who is Alice's best friend. Say it as a secret, and ask Bob never to repeat this to anyone. Bob's first thought will be to let Alice know.
The "SEsGI" strategy
The Someone Else's Good Idea. Some ideas can not be "good" ideas just because they are yours. (But your boss's ideas are always good). If you want an idea to be thought as "good", just go to people saying "Hey, I just remember the idea you told me about few days ago, and (blah blah blah...)". Very few people are honest enough to answer "Sorry, this wasn't my idea".
mail

Syntax of Windows network shares

\\host\directory is what's called a UNC path. Such paths are not case-sensitive.