HAHA, IT IS DONE. WE HAVE BATTLED FOR WEEKS, BUT YOU HAVE FINALLY SUBMITTED. SUBMITTED TO BEING MY SERVANT, TO BEING THE COURIER OF MY MAIL.
AND YOU WILL FUCKING SIGN IT WITH MY DKIM SIGNATURE, FOR I HAVE DECREED IT.
For those of you wondering what the hell that was about, I've recently spent an inordinate amount of time trying to get exim to sign my emails with a DKIM (Domain Keys Identified Mail) signature, in order to reduce the likelihood of it being considered spam.
For those unaware, DKIM (Domain Keys Identified Mail) is a process in which a private key is used to sign the emails prior to their delivery to another mail server. The receiving server can then lookup the domain of the sender to get the public key, which it uses to validate that the email has originated from somewhere controlled by the domain owner.
Effectively, DKIM is a system to ensure that mail is coming from the domain it's proclaiming to be from, because despite what most consumer software might have you believe, anyone can send an email pretending to be from support@apple.com;
it's as simple as
echo "To: user@domain.com
Subject: Password Reset
From: support@apple.com" | sendmail -f "support@apple.com" user@domain.com
Those fairly simple lines would send an email to user@domain.com
which for all intents and purposes would appear to be from support@apple.com
.
Historically this tended to be a pretty big issue, and is the reason their was so much spam going around in the 90's/00's. More recently, a number of standards have been introduced as a way to validate that a sender is who they say they. Or at least, that their associated with the domain that they say they are (You can do individual sender validation separately, using PGP signing and the web of trust).
The first standard is known as SPF, which is a simple text record associated with the DNS server containing the IP's that can send mail from the specified domain, if an IP is trying to send an email with a from address of apple.com
, but the server's IP isn't in the apple.com
SPF record, then most modern mail servers will assume the email is spam/phishing and refuse to accept it.
The second standard I'll mention is DKIM, which uses public/private key pairs to verify the email and it's contents. The private key is known only to the server, and is used to sign the emails as they leave, the public key is derived from the private key, and as the name suggests, is made public in a DNS record associated with the domain. Any signature made from the private key can be validated against the public key to ensure that it has in fact originated from the origin that it's proclaiming to.
As an aside, this post started as a rant because I wanted to have a whinge about exims' scripting language, which is the reason I've got SPF/DKIM on my mind.
(My issue with exim's scripting language has to do with the lack of an indicator for variables in strings, as opposed to being a regular part of a string. In the snippet below their's nothing to indicate that DKIM_DOMAIN is actually a variable and not just an uppercase section of the string.)
# Commented below each of the assignments is an example of
# what it resolves to.
MAIN_TLS_ENABLE = true
DKIM_CANON = relaxed
DKIM_SELECTOR = 20170405
# Get DKIM_DOMAIN /FROM/ outgoing email header
DKIM_DOMAIN = ${sg{$lc:${domain:$h_from:}}}{^www\.}{}}
#DKIM_DOMAIN = rumblelane.com
# use the file associated with the domain
DKIM_FILE = /etc/exim4/dkim/DKIM_DOMAIN-private.pem
#DKIM_FILE = /etc/exim4/dkim/rumblelane.com-private.pem
# if the file doesn't exist, don't use it.
DKIM_PRIVATE_KEY = ${if exists{DKIM_FILE}{DKIM_FILE}{0}}
#DKIM_PRIVATE_KEY = /etc/exim4/dkim/rumblelane.com-private.pem
In the above code you can see how the configuration looks in exim, we get the domain name (DKIM_DOMAIN) from the sender address, we look for a private key for that domain (DKIM_FILE) and then we set the private key to the file if it exists (DKIM_PRIVATE_KEY), you can also see the selector I've specified for the DKIM record, if I need to support different selectors for different domains in future I could do that with an IF/ELSE IF.
Both standards are, in essence, a way to determine the trust-worthiness of a given communication (in this case, an email), and they do so by publicly declaring that "only communications that originate from these addresses (SPF) or have my signature (DKIM) are from me."
For the curious, you can see my DKIM record here, and my SPF record here (It's the second, the first is my keybase verification).
]]>To steal a quote I used after the earthquakes:
"It's not the end of the world, but you can see it from here."
Hyperbole aside, their's a fair amount to unpack with this Trump victory.
Firstly, I don't think it's the end of the world. Jon Stewart remarked a while back that he believed America was stronger than any one man, at the time he meant to defend against the oppositions implication that Obama would ruin america, but equally the remarks apply to Trump's opposition (and so I guess we'll get to see whether he was right).
Secondly, I feel this victory is indicative of a trend in the western world towards nativism, a recession from globalization because we perceive it as having failed us. A perception influenced by the failure of Greece, the shrinking of blue-collar / middle class jobs, the increase in wealth at the highest levels of society, and by (social-)media zeitgeist's (e.g. the argument's against TPPA/TTIP while having some merit, make's it easy to jump from "TPPA is bad" to "globalization is bad" as globalization is the primary purpose of trade agreements).
So to those of you reading this, I urge you to re-evaluate your beliefs with careful consideration for your aspirations for the world and with regards to the agenda of those informing you, be they politicians or reporters (keep in mind almost everything you read is propaganda, whether it's factual or not).
Thirdly, I believe the Trump victory is the first strong indicator we've had that the fall of the American empire has begun.
I don't mean the fall of the US as a nation, but as a super-power with global influence.
Say what you will about Obama, but he a was fairly competent and savvy politician. He was aware of China's growing influence and power, and attempted to curb it with his economic policies and the various trade agreements (TTIP/TPPA were designed from the outset to exclude China, in order to curb China's economic influence).
Trump on the other hand, has run his entire platform on the notion that he is not a politician (and therefore trustworthy). But his lack of political experience will be absolutely crippling on the world stage, keep in mind that Putin was able to out-maneuver Obama, who is a reasonably savvy politician. To think Trump can go toe-to-toe with other world leaders is laughable.
And Lastly, this victory shows just how wide the gap between the political class and the people of the USA has grown. Just weeks before the election most prominent republicans pulled support for Trump on the back of his "grab 'em by the pussy" remarks, and the Democrats' oppose him for obvious reasons, yet despite having little political backing he still won the election. This certainly indicates that much of the political class in America no longer represent the views of the people.
On a more positive note, we do have a few things to look forward to:
(I've attached Charlie Chaplin's speech from "The Great Dictator" (which is 76 years old!), because it's reflective of my aspirations for the world).
]]>Answers with working can be found at the bottom of this page. The first few questions are relatively straight forward. The thing to remember with algebra is that you don't always get a clean answer. when presented with an equation like \( (x+2)(x+1)=\) you'
]]>Answers with working can be found at the bottom of this page. The first few questions are relatively straight forward. The thing to remember with algebra is that you don't always get a clean answer. when presented with an equation like \( (x+2)(x+1)=\) you're unlikely to get to a simple \( x = ??\) position.
So try not to get too hung up on looking for that.
What I found when I was learning algebra was that sometimes I would forget the basic rules. For examples sometimes I would do the following:
\[ (x + y)^2 = \]
\[ (x + y)(x + y) \]
\[ = x^2 + xy + yx + y^2 \]
But that goes against one of the primary rules, namely that we keep to alphabetical order. The correct answer is \( x^2 + xy + xy + y^2 \) which can then be simplified to \( x^2 + 2xy + y^2 \). Messing it up made me think that \(xy\) and \(yx\) were different numbers, when they're actually the same number.
mathematicians are lazy. They like to shorten everything they can in an equation. for example \( 3 \over 4 \) is used as a shorthand for \( 3 \div 4 \), and when you see two mathematical objects next to each other without a symbol between them then multiplication is implied.
For example, \( 3(x) \) is really just \( 3 \times x\) and \( 3abc \) is really \( 3 \times ( a \times b \times c ) \).
So for a substitution equation like \( 3a + 2b - c = T\) then what they're actually asking is \( (3 \times a) + (2 \times b) - c = T\).
The substitution stuff appears to be more or less to improve your ability to use formula's, which is a large part of advanced mathematics.
Algebra is really just a way to represent complex relationships in mathematics. If you're having trouble understanding a question below, try to relate it back to something in the real world (a lot of your stuff will be based on geometric shapes. Senior maths generally uses graphs for Algebra).
So with regards to these questions, we're expressing values in terms of there relationships. So for question a) we can see for the sides representing the otherside of the shape there are two values, \( y \) and 8
. We can represent there relationship with the \( * \) side with the following:
\[ * = y + 8 \].
For b), we're doing the same. writing an expression that represents the relationship of these values to one another, and in relation to the perimeter of the object (where the \(perimeter = 2(x) + 2(y)\) or put another way \(P = 2(x+y)\)).
\[ 2((y+2)+6) + 2(y + 8) \]
would give us the full rectangle. However, there's a bit missing from the object, which we need to subtract from our rectangle in order to accurately represent the object. The bit that's missing has a perimeter that can be described with the following expression (because it's a rectangle too):
\[ 2(y + 6) \]
You'll note that not the whole perimeter of the missing bit is missing, only the bottom half of it. Thus we only need to deduct half of it's perimeter. Giving the following:
\[ 2((y+2)+6) + 2(y + 8) - (y + 6) \]
\[ 2(y+8) + 2(y + 8) - (y + 6) \]
\[ 2y + 16 + 2y + 16 - y - 6 \]
\[ 4y + 32 - y - 6 \]
\[ 3y + 26 \]
For c), we plug the new value into our final equation from b) so that we have \( 3y + 26 = 44 \) giving us an equation we can solve.
\[ 3y + 26 = 44 \]
\[ 3y = 44 - 26 \]
\[ 3y = 18 \]
\[ 3y \div 3 = 18 \div 3 \]
\[ y = 6 \]
Factorizing is the inverse of expanding in normal algebra. Where normally we're given an equation like \( 12y(3 - x) \) and asked to expand it, factorising asks the opposite of us.
It gives us \( 36y - 12xy \) and asks us to re-arrange it. In this case, we can see that 36 and 12 are both divisible by a few numbers, 3, 4, 6, and 12. For the greatest simplification we choose the largest number that is a factor of both numbers (it, when multiplied by two other numbers fits into both of the numbers in our equation). so the first step is \( 12(3y - xy) \). But we can see further to this that both items in the parentheses are being multiplied by y
so we can remove it too. Thus giving us \( 12y(3 - x) \).
In general, the point of factorising is to re-arrange the equation. We're not trying to solve it, so we shouldn't be disappearing numbers (just re-arranging them).
It get's a bit more complex if you're doing quadratic polynomials. I suspect that's a bit beyond what's expected of you, so feel free to skip this section and questions 10 & 11 if you're pressed for time.
With a quadratic you're given an equation that will look like the following \( ax^2 + bx + c = 0\) which you'll hopefully recognize as being the end result of expanding an equation like \( (x + i)(x + j) \).
(often the = 0
might be skipped, that's OK, we're just showing it's there so that we know there's nothing on the otherside of the equation).
Of particular importance in the above equation is the relationship between the numbers b
and c
.
Specifically, they're made up of two smaller numbers, we'll call them i
and j
. The relationship between b
and c
and there factors i
and j
can be expressed as \( b = i + j \) and \( c = i \times j\).
The hard part is working out what i
and j
are. I'm not currently aware of any easy formula for working this out. You just have to pick numbers and check that they work.
For example, if we have a quadratic to factorize that looks like \( x^2 + 17x + 72 \) then we have \( b = 17\) and \( c = 72 \). If we cycle threw numbers looking for values for i
and j
that add up to 17 but multiply out to 72 we should eventually end up with 8 and 9 ( \( 8 \times 9 = 72 \) and \( 8 + 9 = 17 \).
Thus we can factorize out the equation as follows:
\[ x^2 + 17x + 72 \]
\[ x^2 + 17x + 72 = x^2 + x(8 + 9) + 72 \]
\[ x^2 + x(8 + 9) + 8(9) \]
\[ x(x) + 8x + 9x + 8(9) \]
\[ x(x + 9) + 8(x + 9) \]
Note in the above line we've ended up with \( (x + 9) \) twice. We can rewrite the equation so that it only shows once by group the two things it's multiplying against, giving us:
\[ (x + 9)(x + 8) \]
Q.E.D.:
\[ x^2 + 17x + 72 = (x + 8)(x + 9) \]
So to recap:
We're doing the inverse of what we normally do. Instead of expanding the equation out, we're contracting it by looking for common base numbers throughout the equation.
It also helps that when you're multiplying numbers it doesn't matter which way round they go \( 4 \times 5 \) is the same as \( 5 \times 4 \). This means the order when your factoring the equations doesn't matter.
What does matter though, is the sign. \( -4 \times 5 \) is not the same as \( 4 \times 5 \).
Also, keep in mind the shorthand we're using. \( 8(9) \) really just means \( 8 \times 9 \) and \( x(8 + 9) \) really means \( x \times ( 8 + 9 ) \).
Perimeter of a rectangle:
\[ P = 2x + 2y \]
Area of a Circle:
\[ A = \pi r^2 \]
\[ \pi = 3.14 \]
\[ (x + 4)(x - 8) = 0\]
\[ 3(x + y) = 0\]
\[ (5 - x)^2 = 0\]
\[ (x - y)^2 = 0\]
Tommy is measuring a $20 bill that he has in his possession. He notes that the top and bottom sides are three times as long as the left and right sides of the bill. Write an equation that expresses this relationship with regards to the perimeter of the $20 bill.
To answer this question You'll need the perimeter formula, and it might be helpful to draw the object being described.
\[ 64 - 4x = 48 - 5x \]
\[ 20 - 5x = 48 - 6x \]
\[ x^2 - 40 = 24 \]
\[ x^2(x + y) = 0\]
(HARD) Factorize the following: \[ x^2 - 10x + 25 = 0\]
(HARD) Factorize the following: \[ x^2 + 32x + 48 = 0\]
Factorize the following: \[ 12x - 12 = 0\]
Factorize the following: \[ 36x^2 - 12x = 0\]
Factorize the following: \[ 11x^3 + 15x^2 = 0\]
Given a circle with a radius of 4cm's, find the area of the circle (show your working). You can find the radius formula for substitution in the Formula section above.
Example Answers: \[ (x+2)(x+1) = 0\]
\[ (x+2)(x+1) = x^2 + x + 2x + 2 \]
\[ ( x + 2x = 3x ) \]
\[ (x+2)(x+1) = x^2 +3x + 2 \]
Answers to the questions begin here:
\[(x + 4)(x - 10) = 0 \]
\[ x^2 - 8x + 4x - 32\]
\[ (-8x + 4x = -4x) \]
\[ x^2 -4x - 32 = 0\]
\[ 3( x + y ) = 0 \]
\[ 3x + 3y = 0\]
\[ (5 - x)^2 = 0 \]
\[ (5 - x)(5 - x) \]
\[ x^2 - 5x - 5x + 25 \]
\[ (-5x - 5x = -10x) \]
\[ x^2 - 10x + 25 = 0 \]
\[ (x - y)^2 = 0 \]
\[ (x - y)(x - y) \]
\[ x^2 + y^2 - xy - xy \]
\[ ( -xy - xy = -2xy ) \]
\[ x^2 + y^2 - 2xy = 0 \]
The formula for the perimeter of a rectangle is \( perimeter = 2x + 2y \) where \(x\) is the top/bottom and \(y\) is the left/right side. As per the question, we know that \( x = 3(y) \) (because the top/bottom is 3 times as long as left/right side is high). So our equation should look something like the following:
\[ perimeter = 2(y)+2(3y) \]
\[ perimeter = 2y + 6y \]
\[ perimeter = 8y \]
\[ 64 - 4x = 48 - 5x \]
\[ 5x - 4x = 48 - 64 \]
\[ x = -16 \]
\[ 20 - 5x = 48 - 6x \]
\[ 6x - 5x = 48 - 20 \]
\[ x = 28 \]
\[ x^2 - 40 = 24 \]
\[ x^2 = 24 + 40 \]
\[ x^2 = 64 \]
\[ \sqrt x = \sqrt 64 \]
\[ x = 8 \]
\[ x^2(x + y) = 0\]
\[ x^2(x + y) = x^3 + x^2y \]
\[ x^2 - 10x + 25 = 0\]
\[ x^2 - x(5+5) + 5(5) \]
\[ x^2 - 5x - 5x + 5(5) \]
\[ x^2 - 5(x) - x(5) + 5(5) \]
\[ x(x) -5(x) - x(5) + 5(5) \]
N.b \( 5 \times 5 \) equals the same as \( -5 \times -5 \) (as a double negative is a positive). So we can swap the sign of \( 5(5) \) to match the rest of the equation at this point.
\[ x(x) - 5(x) - x(5) - 5(-5) \]
\[ x(x - 5) - 5(x - 5) \]
\[ (x - 5)(x - 5) \]
\[ (x - 5)^2 = 0\]
\[ x^2 + 19x + 48 = 0\]
\[ x^2 + x(19) + 48 \]
\[ x^2 + x(3+16) + 3(16) \]
\[ x(x) + 3x + 16x + 3(16) \]
\[ x(x) + 3(x) + x(16) + 3(16) \]
\[ x(x + 16) + 3(x + 16) \]
\[ (x + 3)(x + 16) = 0\]
\[ 12x - 12 = 0\]
\[ 12x - 12 = 12(x - 1) \]
\[ 36x^2 - 12x = 0\]
\[ 36x^2 - 12x = 12x(3x - 1) \]
\[ 11x^3 + 15x^2 = 0\]
\[ 11x^3 + 15x^2 = x^2(11x + 15) \]
Keen in mind that \(11x^3\) just means \(11 \times x \times x \times x \), which is how we can factor it out without issue.
\[ A = \pi r^2 \]
\[ \pi \times 4^2 \]
\[ 3.14 \times 4^2 \]
\[ 3.14 \times 16 \]
\[ = 50.24cm \]
This is a simple substitution given a formula which you can find under the formula section at the top of the page.
This is the first entry in my attempt to create a game from scratch.
Firstly, I feel like justifying myself. I don't have any illusions of grandeur, no great idea's for a game "that will change the world!". I was just curious about the
]]>This is the first entry in my attempt to create a game from scratch.
Firstly, I feel like justifying myself. I don't have any illusions of grandeur, no great idea's for a game "that will change the world!". I was just curious about the challenges and problem solving that goes into the creation of games.
It started out innocently enough, "I wonder what a simple client/server game protocol would look like." Being that most of my programming experience has been in python I figured it was a good enough place to start. I realise that a lot of people consider python to be pretty slow for these sorts of things, and well, it probably is. But I don't need it to be fast. I just need a functional prototype, and python with it's sockets, select calls, and structs seemed comparable to the more commonly used C-family of languages.
Needing a starting point I did some googling to see what people recommended, and the following is what I've ended up with. On the server side, I have a multi-threaded socket servers that spawns a new thread for each socket connection. I was originally using system.fork()
instead of threading but I had trouble sharing resources between the separate processes.
This server is connected to using a socket on the client side which sends packed structs over TCP. The server then interprets these structs and sends back a similar packet containing the information requested (or in possible future cases, simply an acknowledgement).
The layout of the structs is currently three unsigned ints followed by the payload.The first unsigned int is the length of the packet (the number of bytes in the message), this number includes the length of the length. This was a late addition to the protocol that I found I needed in order to distinguish between separate messages (as they would sometimes all come in at the same time).
The second unsigned int is the protocol version number (which is currently 256).
I chose 256 because in hex 256 this is represented as 0x100
. This structure allows me up to 255 minor versions. Specifically, I can use the first value as a major version, the second as a minor version, and the third as a minor-minor version number (allowing each a value between 0 and 15 inclusive). In most common programs a major version increase indicates changes that aren't backwards compatible, a minor version increase indicates new features that are backwards compatible, and a minor-minor version increase would be a bug fix or some other non-breaking change.
The third unsigned is just an identifier so we know what the packet is regarding and how we should interpret any commands given. In some cases, this value is enough to know what they're asking. For example, a 2
identifier indicates they're asking to know what player they are without us having to look up a command.
With that issue solved, I needed to actually create a world that I could have two separate clients move around in, allowing me to test the protocol.
This world has ended up being a simple 2 dimensional array, creating a kind of matrix. An example usage would be matrix[x][y] = Grass()
. However that's not quite how things ended up. Because I wanted to have sensible access to the matrix in the form of:
for line in matrix:
for tile in line:
print(tile)
what I've actually ended up with is backwards co-ordinates matrix[y][x] = Grass()
. Which while not ideal, is still functional so long as I'm consistent.
I quickly decided that an empty grid wasn't much fun, so had to find a way to make it more interesting. With that in mind, I turned the grid into a sort of maze with the following.
When we first generate the world we fill it with Walls. Afterwards, we generate a number of rooms into the matrix, and then we fill in the rest with a maze. We then clean up any dead ends in the maze. Ideally what I'd like to do is connect each room together instead of building a maze, but the algorithms for doing so were a bit hard to get my head around.
The rooms were mostly what it sounds like, I would randomly choose a width and height from within a given set, by supplying a minimum and maximum value, and then randomly selecting a number from between the two. Then we'd randomly select a point on the map and check that each tile within the square steaming from that point was a wall. If any tile was already empty it meant our new room was going to overlap with an existing room, so we'd stop and try again. Otherwise we'd replace each of the tiles within that square with an empty tile.
The Maze generation was a bit more complicated. I mostly ended up stealing an algorithm for this from else where in the web. For it, we started by selecting a point on the map and then moving in a direction from there. Each time we moved, we check each of the four surrounding tiles from our selected tile, from these we using a weighted number, choose a direction to go in (somewhat favouring the previously used direction so that it doesn't devolve into a windy mess) and then we replace that grid position and the next 2 with an empty tile. I haven't done a very good job of explaining this because I'm still a bit vague on how it works exactly.
In any case, after we've done that we go through and remove all the paths that lead to a dead end, which makes the maze a bit neater and less random.
The end result is this:
To get all of this actually playing nicely I had to create a client that could connect to our server. I briefly discussed it earlier. The client is made up of three threads, a networking thread, a draw thread, and an input thread.
The networking thread pulls commands from a network queue and sends them over a socket to the server. It also reads responses from the server and uses them to update the world, after which it tells the draw thread to redraw the world.
The draw thread draws the world to the terminal using simple ASCII characters. Currently it uses a 'clear' command to clear the screen before the redraw.
The Input thread handles character input. Because I'm doing all of this in the terminal I'm beholden to the rules of the terminal, with the main one being that by default the input is read on a per line basis. Meaning any key press has to be followed by a new line (the enter button by default) before the game will pick it up. I can hack around this by setting the terminal to raw mode, but this breaks the formatting of my draw calls, which I'm too lazy to look into and fix.
So while the input situation isn't ideal, it's at least functional.
The resulting code can be found Here.
Next week, I'll have a go at real OpenGL rendering and maybe port the whole thing over to c++, which will be fun as I have no experience at all with c++ (and only minor experience with C)
When I started this I had no idea what I was going to end up with, or how far I'd even get. But after creating a world, a network protocol, and a client/server application, I think I'll keep going. Not sure what the end product will be, be at the moment I'm leaning towards either something Dungeon Keeper-y, or something like the original Pokemon games.
]]>On December 31st, 2016 the day will be a full second longer than a normal day, instead of there being 86400 seconds in the day, there will be 86401 seconds. That's weird right? time is supposed to be this consistent thing. There are always 60 seconds in a
]]>On December 31st, 2016 the day will be a full second longer than a normal day, instead of there being 86400 seconds in the day, there will be 86401 seconds. That's weird right? time is supposed to be this consistent thing. There are always 60 seconds in a minute, always 60 minutes in an hour, and always 24 hours a day. so their should always be 86,400^{1} seconds in a day.
So if that's the case, then why does the 31st of December, 2016 have an extra second?
The answer has to do with the rotation of our favourite celestial body around the sun. But before we get to that, I'll fill you in on some of the background.
It's an odd question, a bit like asking "how long is a piece of string?"
The answer lies in how we measure seconds. In 1900 a second was defined in terms of the period of the Earth's orbit around the sun, we had agreed on the number of days in a year, and knew that we wanted 24 hours in a day, 60 minutes in an hour, and 60 seconds in a minute. So in 1900 we defined the second as being \(1 \over 31,556,925.9747\) of the year^{2}. Since then we've developed the International System of Units (SI), which is an attempt to define various measurements using universal constants (that way they're not dependent on an object or a location, so we can record time even when we're not on the earth). The SI currently defines a second as:
The second is the duration of 9,192,631,770 periods of the radiation corresponding to the transition between the two hyperfine levels of the ground state of the cesium 133 atom.
What this means is that the second is considered to be about 9 billion vibrations from a cesium 133 atom. The "ground state" part means that the atom needs to be at rest (for earth, that means sea level), and 0 degrees kelvin. It's a very large, weird number because we've worked backwards to get it. We knew how long we wanted a second to be, we just needed to find some way to express it that didn't require anything specific to our environment.
Now the reason we have an extra second is because scientists use something called an Atomic Clock, to measure time. An atomic clock uses the SI definition of a second to measure time, which gives them an extremely accurate measurement. However, the downside is that the accuracy of the atomic clock no longer matches the original definition of a second, the one based on the earth's rotation of the sun.
"why don't they just adjust the definition of a second then? just knock off a few thousand vibrations!" I hear you say. The issue isn't the length of the second, so much as it is the speed at which the earth rotates the sun. As it happens, the earth doesn't rotate the sun at a consistent speed, and lately it's been slowing down by about 1 seconds every few years. The result is that in order to keep our atomic clocks from getting out of sync with earth time, we have to occasionally add a second on to the end of the day.
Generally, the seconds are added either at the end of June, or at the end of December, but this isn't a hard rule. The International Earth Rotation and Reference Systems Service (IERS) group usually announce coming leap seconds giving around 6 months notice for the impending adjustment.
That's all a bit interesting, but the final question you're probably wondering about is "Why does this matter?"
The answer to which is that lots of computer systems make assumptions about the behaviour of time. Assumptions that are often wrong when it comes to the inclusion of leap seconds.
The problems arise from how the extra second is handled, with different systems applying different solutions to how they add the extra second, all of which having potential downsides.
For example, some systems repeat the last second of the day so that 23:59:59 occurs twice, however this can causes issues with databases (where time is recorded to the millisecond and expected to be unique, if the same second occurs twice a timestamp collision could occur), it's also possible for this solution to create vulnerabilities in security systems that rely on random numbers (as random is often seeded from the current time, duplicating the time weakens the security).
Other systems like Google, make tiny adjustments throughout the day so that the time at the end of the day is correct, this avoids issues caused by collisions (which is highly likely to occur at Googles scale), but the downside of this approach is that the time is off by an increasing amount throughout the day, which can cause issues when interacting with systems that don't adjust the time in this manner.
The final and recommended approach to handling the extra second is to just add an extra second after 23:59:59 so that the next tick is 23:59:60, instead of 00:00:00. This avoids issues with timestamp collisions and any issues that might occur from having the time just be wrong for the entire day. The problem with this solution is that next to no software makes allowances for a 61st second (because it's so rare), and as a result much of it either crashes or encounters undefined behaviour (which just means nobody know's what it's going to do).
This probably all sounds like posturing, but in 2012 the addition of a leap second caused both Qantas' and Reddit to crash.