Stories
Slash Boxes
Comments

SoylentNews is people

Log In

Log In

Create Account  |  Retrieve Password


prospectacle (3422)

prospectacle
(email not shown publicly)

Journal of prospectacle (3422)

The Fine Print: The following are owned by whoever posted them. We are not responsible for them in any way.
Friday February 03, 17
06:16 AM
Reviews

I'm about a third of the way through this book, it's a fantasy/action type deal and I'm finding it does a better than usual job of painting the state of mind of different characters without slowing down the plot.

There's a sample chapter at link below, if you're into this sort of thing.

(Update: Charon pointed out the chapter at that link has formatting issues. https://heartofnightsaga.com/2017/02/02/download-a-free-sample-chapter/

A better version of the sample chapter is at the amazon page:

Sample chapter at Amazon

Incidentally the Kindle version seems to have a longer free sample than the print one.)

Would be interested to hear other people's thoughts. Or else: what are you reading at the moment that you like (preferably something with sample chapter available so I can check it out before buying).

Monday February 15, 16
01:13 PM
Code

Besides voting, I'm not sure what I can do to change the Australian government's horrific, inhumane, disgusting way of dealing with asylum seekers. However, this article made me think about the fact that one day this will be a shameful period taught in history class:

http://www.smh.com.au/comment/nauru-detention-centre-clock-ticks-on-our-addiction-to-fictions-of-asylumseeker-policy-20160203-gml6or.html

So for the record I want to say this, which seems too obvious to need saying, but apparently escapes the attention of everyone involved in deciding our refugee policy:

1 - Sending people offshore to send the message that they won't be settled in australia if they try to come by boat, doesn't mean we have no duty of care to those people once they're locked up in the detention centres we organised for them in Nauru or Manus Island.

We (our government) arranged, paid for, and sent people to these detention centres. They're in other countries but that's our choice, a service we're paying for, and so it's our responsibility to make sure we're getting the service we want. If we don't require level of safety, health, and dignity that would be required by law in any refugee centre on our soil, then we're paying to have people mistreated.

2 - Deterring people from trying to come by boat, with the justifcation that we're trying to stop deaths at sea, does not mean any and all levels of danger, abuse, psychological scarring, or disease are worth accepting for this end.

If the government is really just trying to tell refugees that they shouldn't pay illegal people smugglers to bring them to australia, then removing them from australia when they get here is enough. Anything beyond that is cruel and unusual punishment.

3 - If conditions are ok, acceptable, humane and secure on these off-shore detention centres then doctors need not be gagged, and humanitarian organisations and journalists need not be banned.

Whatever excuses are provided for this cone of silence fail to answer the question: How we do know if the conditions are legally and humanely valid, if all we have to go on is the word of the minister? That's no way to demonstrate competence or honesty, and this is supposed to be a representative democracy.

I'm fairly confident this post will make no difference. But I felt the need to say something, because I'm going to be lumped in historically will all the people who let this happen.

Thursday January 28, 16
10:59 AM
Code

To improve accuracy instead of just overall speed, and to create more tension (and, as it turns out, swearing) during gameplay, I've made a version of my typing game where one single mistake ends the game and you have to start the level again.

http://typerise.com/sudden_death.php

You start by having to type 50 consecutive characters correctly before 60 seconds runs out, then on the next level it's a hundred characters within 60 seconds, then 150 characters on level 3, and so on.

Let me know what you think (and if you like it, what level you complete). I once beat level 8 but I think it was a fluke.

Tuesday December 15, 15
05:48 AM
Code

This was hard and annoying to figure out. So I thought I should tell the internet in case it helps anyone else.

Basically I wanted to know if people were viewing my website on a small screen*

A quick summary of the problems:
- Many mobile devices lie about dpi, screen size, and window size, whether you check with css media-queries or javascript.
- Different browsers report different size numbers on the same device.
- Screen-width (in pixels) doesn't tell you anything about the physical screen size. Several high-end phones have more pixels than your average laptop.
- There is no (supported) standard way to just ask a browser "are you on a phone"
- I don't like using user-agent-strings as it's ugly (you need to keep a big list) and unreliable (users can change or remove it).
- I don't like feature checking for a lot of non-standard browser apis with various prefixes to search for the information. It's ugly, and I don't want to play along with browsers that ignore the standards. We should be past that by now.

This solution is simple. It's not perfect but it seems to work on all of the many devices and browsers I've tested. However I've dealt with web-browsers long enough to know I might have missed something. Any feedback is welcome.

Summary solution:
1 - Set a normal "viewport" meta tag. This is pretty standard and (should) only affect mobile browsers.
2 - Check if the browser is taking up the full screen.
3 - Read the virtual (css-pixels) width of an element that takes up the full window-width.

On probably 99% of smart phones, the browser takes up the full screen. So if you have an element that takes up the full-width of the window, it can tell you how (virtually) big the screen is. Then you can decide whether it's big enough to include a desktop-style interface.

Details:
1 - <meta name="viewport" content="width=device-width, initial-scale=1.0">
2 - if ((outerWidth == screen.width) || (innerWidth > outerWidth)) Then you're in fullscreen. That second conditions is a kludge to make it work on iphones who choose not to make the outerWidth work.
3 - <div style='position:absolute; left:0px; right:0px;'> </div> Read the .offsetWidth of this div and it will tell you the virtual/viewport width of the document. Even in portrait mode almost all phones will be less than 700. Virtually no laptops or desktops will. If you have a small-screen netbook or tablet in portrait mode then it might fall below this threshold. Of course you can use a lower threshold depending on your purpose.

Hope this helps. If it seems overly complicated, I'd like to see a simpler solution (really).
----------------------------

*The best interface for a desktop is not the best interface for a phone and vice versa. There have been many, ridiculous attempts to make a single unified interface which usually end up showing as many useful features on a desktop screen as you can reasonably fit on a phone.

Friday July 03, 15
03:37 AM
/dev/random

The quality of your plans affects the quality of virtually everything you do, including how much you enjoy doing it. Here are some thoughts on the subject. Suggestions welcome.

1. A good plan is its own reward. Don't worry about when a plan will pay off; focus on making it well and it will pay off immediately.

2. Things you wouldn’t think of in five years of planning will be obvious within five minutes of trying to implement the plan. If you want your plans to be realistic, test things out then reconsider.

3. Remembering the details of a plan clearly and at the right times is as important as making it in the first place, and sometimes requires more effort.

4. The most reliable way to think about a plan more clearly is to write about it for ten minutes.

Friday March 27, 15
12:58 PM
Code

I made some small improvements to my typing-testing and training game: http://typerise.com/

All the source texts are public domain classics and a strange thing happens if you play for a few minutes at once. The act of typing becomes less and less conscious until you start reading the text properly, instead of just copying it. You might be interested what the book is and where you can read the whole thing, so now it tells you the title and links to the project gutenberg page for that book, which has a variety of text/ebook formats you can download.

There's also some minor formatting and labelling changes. Any suggestions or feedback is welcome.

Feel free to take the code and adapt it to your own purposes.

Monday February 23, 15
11:54 AM
Hardware

Autobiography: Noun, singular. The story of your first car.

Early autobiographies were short articles within the leisure section of a weekend newspaper, describing the owner's first car, its appearance, price, and the driving experiences it provided.

In the modern era, the genre has become vastly more sophisticated, often running to a length comparable with a novel or automotive repair manual. These book-length autobiographies may include multiple chapters before the car is introduced, setting the background to vehicle ownership, including relevant details from the writer's early life that shape their circumstances, character, and outlook; and inform the important and life-changing choice of first automobile.

The broader effects and transformations that result from having the freedom to drive wherever you want, whenever you want, and the specific limits of this freedom in the individual's case, are then explored in detail. As the genre has become more established and its tropes more familiar and predictable, some authors have chosen to only describe the machine in question indirectly, or by implication.

Later chapters may be set in the period after the car has been sold or given away, focusing on the long term effects the car had on its owner's life. Subsequently purchased cars and the circumstances surrounding their acquisition and use, may be addressed, for the purpose of comparing these eras of the writer's life with the first and most formative experience, which must necessarily act as the standard against which all other times of life are judged.

Books of this genre can today be found in most chain bookstores and car dealerships. They are also available in some of the larger public libraries.

Saturday August 23, 14
02:55 AM
Code

If you want to practice or test your typing I've been working on a little webpage game for this purpose. No login or plugins required, but of course it needs javascript as it measures keystrokes.

Thanks to Paulej72 for finding a bug in safari, which is now fixed.

It uses excerpts of public domain texts, like sherlock holmes and moby dick, which I pilfered from the very excellent project gutenberg.

Any suggestions or bug reports or whatever comments are most welcome. I intend to improve the game further, such as adding optional logins to remember your score, and also links to the whatever book you're typing from at the time in case you like it and wish to read the whole thing.

Sunday May 04, 14
12:49 PM
Code

On IRC (in #Soylent), MrBluze and I have been discussing how to make a better messaging system. You would need to be able to easily send to individuals or groups, have messages either public or private, be able to verify that the message came from who it claims to be from (and someone who's a contact on your list), and all without relying on specific server software or a specific hosting company).

So below is a very basic proof of concept that does the following:
- Creates two identities (a sender and recipient).
- Gives them each a public and private key
- Creates a message that the recipient can verify is:
          - Intended for, and only readable by the recipient.
          - Created by the sender, and not just someone using their name.
- Formats the result in plain text (base64 encoded) so it's easy to transmit.

This means the message itself could be send via any text medium, public or private, as only the intended people will be able to read its contents and they'll know who sent it based on the message itself.

It's all very basic and preliminary but I had to figure out a few things about how to use openssl and hashes properly, so it may be instructive to other people interested in this kind of thing.

I'll get around to adding more comments at some point.

<?php

function encrypt_longer_string_public_key($source_string, $key, $chunk_length=100,$delimiter = "...")
{
    $source_array = str_split($source_string, $chunk_length);
    $result_string = "";

    foreach ($source_array as $source_chunk)
    {
        $encrypted_chunk = "";
        openssl_public_encrypt($source_chunk, $encrypted_chunk, $key);
        if ($result_string != "") $result_string.=$delimiter;
        $result_string.= base64_encode($encrypted_chunk);
    }
    return $result_string;
}

function encrypt_longer_string_private_key($source_string, $key, $chunk_length=100,$delimiter = "...")
{
    $source_array = str_split($source_string, $chunk_length);
    $result_string = "";
    foreach ($source_array as $source_chunk)
    {
        $encrypted_chunk = "";
        openssl_private_encrypt($source_chunk, $encrypted_chunk, $key);
        if ($result_string != "") $result_string.=$delimiter;
        $result_string.= base64_encode($encrypted_chunk);
    }
    return $result_string;
}

function decrypt_longer_string_private_key($encrypted_string, $key, $delimiter="...")
{
    $parts = explode($delimiter, $encrypted_string);
    $number_of_parts = count($parts);
    $result_string = "";
    foreach ($parts as $one_part)
    {
        $one_part = base64_decode($one_part);
        openssl_private_decrypt($one_part, $decrypted_part, $key);
        $result_string.=$decrypted_part;
    }
    return $result_string;
}

function decrypt_longer_string_public_key($encrypted_string, $key, $delimiter="...")
{
    $parts = explode($delimiter, $encrypted_string);
    $number_of_parts = count($parts);
    $result_string = "";
    foreach ($parts as $one_part)
    {
        $one_part = base64_decode($one_part);
        openssl_public_decrypt($one_part, $decrypted_part, $key);
        $result_string.=$decrypted_part;
    }
    return $result_string;
}

function verify_hashed_string($string_with_hash, $hash_algorithm = "sha256")
{
    $extracted_hash = substr($string_with_hash, -64);
    $extracted_text = substr($string_with_hash, 0, -64);
    $calculated_hash = hash($hash_algorithm, $extracted_text);
    if ($calculated_hash == $extracted_hash) return $extracted_text;
    else return false;

}

// 1) Create a new key:
putenv("OPENSSL_CONF=c:\\wamp\\www\\nospamplease\\openssl.cnf");

if (file_exists(getenv('OPENSSL_CONF'))) print "config file exists<br><Br>";

$config_args = array(
    'config' => getenv('OPENSSL_CONF'));

$sender_key = openssl_pkey_new($config_args);
$recipient_key = openssl_pkey_new($config_args);

// 2) Extract the private key string.
print "sender key is "; var_dump($sender_key); print "<br><br>";
print "recipient key is "; var_dump($recipient_key); print "<br><br>";

openssl_pkey_export($sender_key, $sender_private_key, NULL, $config_args);
openssl_pkey_export($recipient_key, $recipient_private_key, NULL, $config_args);

// 3) Get the public key.
$key_details = openssl_pkey_get_details($sender_key);
$sender_public_key = $key_details["key"];

$key_details = openssl_pkey_get_details($recipient_key);
$recipient_public_key = $key_details["key"];

// 4) Display the keys. The hash of the public key could be used as a "to" identifier.
print "Sender Private Key: $sender_private_key<br><br>
    Sender Public Key: $sender_public_key<BR><BR>";
print "<hr>";
print "Recipient: Private Key: $recipient_private_key<br><br>
    Recipient Public Key: $recipient_public_key<BR><BR>";

// Show some text before and after encryption and decryption
$original_text = "This is totally a secret message";

// Add a checksum to the end.
$inner_message_hash = hash("sha256", $original_text);
$hashed_inner_string = $original_text.$inner_message_hash;

// Encrypt the message with senders private key.
$inner_encrypted = encrypt_longer_string_private_key($hashed_inner_string, $sender_private_key);

// Add a checksum to the end of the encrypted messaged, after a base64_encode of it.
$outer_message_hash = hash("sha256", $inner_encrypted);

$hashed_outer_string = $inner_encrypted.$outer_message_hash;

$outer_encrypted = encrypt_longer_string_public_key($hashed_outer_string, $recipient_public_key);
//$outer_encrypted_as_string = base64_encode($outer_encrypted);

print "<br>Original message:<br>$original_text<br>";
print "<br>Hashed inner string:<br>$hashed_inner_string<br>";
print "<br>Inner string encrypte:<br>$inner_encrypted<br>";
print "<br>Outer string (inner string encrypted + hash of encrypted string)<br>$hashed_outer_string<br>";
print "<br>Outer string encrypted:<br>$outer_encrypted<br><br>";

// Now go the other way, decrypt it and show the decrypted message. Verify each step.

$outer_decrypted = decrypt_longer_string_private_key($outer_encrypted, $recipient_private_key);
$outer_decrypted = verify_hashed_string($outer_decrypted);

if ($outer_decrypted) print "outer decrypted is : ".$outer_decrypted."<br><br>";
else {print "couldn't verify outer decryption";return;}

$inner_decrypted = decrypt_longer_string_public_key($outer_decrypted, $sender_public_key);
$inner_decrypted = verify_hashed_string($inner_decrypted);
if ($inner_decrypted) print "Inner decrypted is: $inner_decrypted";
else {print "couldn't verify inner decrypted"; return;}

?>

Sunday March 30, 14
08:44 AM
Code

Here's a third version of my voting program. Unlike the previous version, it doesn't allow duplicate ranks (you can't rank two candidates as equal first, or equal second, etc).

It can be run on a set of text-based votes, e.g. emails or forum-comments. It recognises and counts valid votes, and filters out invalid data.

It gives a score to each candidate, based on the rank you give it. It is effectively a "Borda Count" voting system (http://en.wikipedia.org/wiki/Borda_count). Version 2 used "Range Voting" and version 1 used "Approval Voting".

I've also tidied the code up a bit, to make it easier to read and simpler to use.

The code below contains example data so you can run it as is, to get an idea of how it works.

<?php

/* How to use this script:

1 - Ask people to write votes that look like this:
    some candidate name = 1
    some other = 2
    another_one = 4
    Any other text will just be ignored.
    Any invalid = votes will be ignored, too
2 - Collect votes. e.g. via email, forum-comments, or a special web-form.
3 - Put all the votes in an array. Each vote should contain its vote-text, and a User ID.
4 - Run this script to filter, parse and count the votes.

*/

// Example candidates:
$valid_candidates = array(
    "candidateone",
    "another candidate",
    "yet another option",
    "somethingelse");

// Example votes:
$votes_array = array(
    // Upper case or lower case doesn't matter.
    array(
        "user_id"=>234,
        "text"=>"
            candidateOne = 1
            Another Candidate = 2
            SomethingElse = 3
        "),
    // Duplicate user. This will be handled properly.
    array(
        "user_id"=>234,
        "text"=>"
            Oops forgot one I like:
            Yet Another Option = 4
            Did I mention:
            CandidateOne = 1
        "
        ),
    // This one contains mostly invalid rankings, and one valid one.
    array(
        "user_id"=>345,
        "text"=>"
            // I hate CandidateOne
            CandidateOne = 6
            Another Candidate = 1
            Yet Another Option = 1
            My friend who's not listed = 3
        ")
    );

// Some options on how the votes are counted.
$allow_duplicate_ranks = false;
$allow_write_in_candidates = false;

// If you allow write-in candidates, specify a maximum possible rank.
// Otherwise the maximum rank equals the number of candidates.
if ($allow_write_in_candidates) $maximum_rank = 10;
else $maximum_rank = count($valid_candidates);

// put valid-user filter in here if necessary
function valid_user($user_id){return true;}

// Arrays to store the counted votes in:
$votes_by_voter = array();
$votes_by_candidate = array();

// Process all votes
foreach ($votes_array as $vote)
{

  // Is it a valid registered user?
  if (valid_user($vote["user_id"]))
  {

    // Process each line of the vote
    $vote_lines = explode("\n", trim($vote["text"]));
    foreach ($vote_lines as $this_line)
    {

      // Does it have an equals sign
      $equals_sign = strpos($this_line, "=");
      if ($equals_sign !== false)
      {

        // Does it have only one equals sign?
        $cleaned_up_line_text = trim($this_line, ";.!\t\n\r\0");
        $parts_of_line = explode("=", $cleaned_up_line_text);
        if (count($parts_of_line) == 2)
        {

          // Get the candidate and rank, make sure they're valid.
          $candidate = strtolower(trim($parts_of_line[0]));
          $candidate_is_valid = in_array($candidate, $valid_candidates);
          $rank = intval(trim($parts_of_line[1]));
          $rank_is_valid = ( ($rank > 0) && ($rank <= $maximum_rank) );

          // Proceed if (it's a valid rank number) and
          // (the candidate is valid, or we're allowing write-in candidates).
          if (($rank_is_valid) && ($candidate_is_valid || $allow_write_in_candidates))
          {
            // Get the score for this candidate.
            // The score is: maximum_rank - (this_rank - 1).
            // For example:
            // - Say there are 5 candidates and the maximum rank is 5
            // - A rank of 1 give it a score of 5.
            // - A rank of 2 gives it a score of 4.
            // - A rank of 5 gives a score of 1.
            // See "Borda Count".
            $score = $maximum_rank - ($rank-1);

            // If this is the voter's first vote, create a voting-record for them.
            // This keeps track of which candidates and ranks they've already voted.
            $voter = $vote["user_id"];
            if (!isset($votes_by_voter[$voter]))
            {
              $votes_by_voter[$voter]["candidates"] = array();
              $votes_by_voter[$voter]["ranks"] = array();
            }

            // Make sure this user hasn't already voted on this candidate
            if (!isset($votes_by_voter[$voter]["candidates"][$candidate]))
            {

              // Make sure the user hasn't already assigned this rank number,
              // or that we're allowing duplicate ranks.
              if ($allow_duplicate_ranks || (!isset($votes_by_voter[$voter]["ranks"][$rank])))
              {

                // Remember that this voter has voted for this candidate,
                // and has used up this rank.
                $votes_by_voter[$voter]["candidates"][$candidate] = true;
                $votes_by_voter[$voter]["ranks"][$rank] = true;

                // Count the vote towards the total for this candidate.
                if (!isset($votes_by_candidate[$candidate]))
                  $votes_by_candidate[$candidate] = $score;
                else $votes_by_candidate[$candidate] += $score;

              } // End of checking if this rank is a duplicate for this voter.
            } // End of check checking if candidate is a duplicate for this voter.
          } // End of check for valid vote values.
        } // End of check for correctly formatted vote
      } // End of check for equals sign
    } // End of for loop for lines of vote text.
  } // of check for valid user.
} // end of for loop for all votes.

print "Who have voters voted for, and which ranks have they used?:<pre>";
print_r($votes_by_voter);
print "</pre><Br>";
print "What score does each candidate end up with<pre>";
// Sort the candidates from highest to lowest
arsort($votes_by_candidate);
print_r($votes_by_candidate);
print "</pre>";

?>