isotope|eleven


About_david_chapman

Better Cryptography in Ruby

by: David A Chapman

April 19th, 2013 09:23

RbNaCl

Cryptography and Ruby just got a litte more acquainted. If you have not heard of djb's crypto library, NaCl, then now would be a good time for you to become a little more acquainted with cryptography and in particular why this crypto library is awesome. I really suggest reading about all the state of the art encryption algorithms used in NaCl because this post will only cover how to use the Ruby library for NaCl.

Crypto You Can Do

Secret-key Encryption

Store some secret stuff with Crypto::SecretBox like so:

# Generate a random secret key
key = Crypto::Random.random_bytes(32)

# initialize a new place to store secret stuff
safe = Crypto::SecretBox.new(key)

# encrypt something using a nonce strategy,
# this can be any number really and it's not secret
# lets use some random bytes though
nonce = Crypto::Random.random_bytes(24)
message = "Coffee and bananas"
cipher_text = crypto_secret_box.box(nonce, message)

# decrypt the message
decrypted_message = safe.open(nonce, cipher_text)
#=> "Coffee and bananas"

Public-key Encryption

Mutual authentication (two-way authentication) can be performed below.

# Dat private key
private_key = Crypto::PrivateKey.generate
# Dat public key
public_key = private_key.public_key

# initialize the safe
safe = Crypto::Box.new(someones_public_key, private_key)
# the other person does this with your key
safe = Crypto::Box.new(public_key, someones_private_key)

# encrypt a message using the box.
# First, do the nonce thingy.
nonce = Crypto::Random.random_bytes(24)
message = "Coffee and bananas"
cipher_text = safe.box(nonce, message)

# Now open the safe
decrypted_message = safe.open(nonce, cipher_text)

Digital Signatures

Digital signatures allow you to publish a public key, then you can use your private signing key to sign messages.

Signer's Perspective

# Generate a new random signing key
signing_key = Crypto::SigningKey.generate

# Sign a message with the signing key
# Signature will be returned in hex format
signature = signing_key.sign(message, :hex)

# Obtain the verify key for a given signing key
verify_key = signing_key.verify_key

# Serialize the verify key to send it to a third party
# Verify key will be returned in hex format
verify_key.to_s(:hex)

Verifier's perspective

# Create a VerifyKey object from a hex serialized public key
verify_key = Crypto::VerifyKey.new(verify_key_hex, :hex)

# Check the validity of a message's signature
# Will raise Crypto::BadSignatureError if the signature check fails
verify_key.verify!(message, signature, :hex)

Hash Functions

A cryptographic hash can be used for checking the integrity of data, but there is no secret involved in the hashing, so anyone can create the hash of a given message.

Hash Functions

# compute the SHA-256 digest of the message.
Crypto::Hash.sha256(message)
#=> "..." # a string of bytes.

# compute the SHA-512 digest of the message and hex-encode it.
Crypto::Hash.sha512(message, :hex)
#=> "ab67..." # a string of hexidecimal bytes.

On a recent project, I had the need to integrate some AngularJS-based interactions within an existing Rails application. I wasn't able to treat it as two separate projects in this case, e.g., a Rails API app/project, that my AngularJS app/project would interact with via XHR. So, here is how I've been able to interact with Rails url/routes and have Rails serve the pre-compiled haml as html.

Let's get started.

Create a new folder within app/views, something like app/views/client_views. Then create a new view for one of your AngularJS controllers, we'll use the typical 'main', so now you'll have app/views/client_views/main.html.haml.

Create a new controller to handle your AngularJS views (app/controllers/client_views_controller.rb)

class ClientViewsController < ApplicationController
  def show
    render params[:id], layout: nil
  end
end

Within your AngularJS app's config, you'll now have the following for the $routeProvider:

angular.module('myApp', [])
  config(function($routeProvider) {
    $routeProvider
      .when('/my_route', {
        templateUrl: 'client_views/main',
        controller: 'MainCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

Lastly, we need to set our routes, so pop open config/routes.rb and add the following route:

resources :client_views, only: [:show]

Now, just to test that we have everything setup correctly, in your browser, visit http://localhost:3000/client_views/main

..and you should see your unstyled 'main' view.

Once that's golden, visit the main route/url you defined in your app config to see the whole thing work: http://localhost:3000/my_route

Boom, you now have rails-served/managed views interacting with your AngularJS app.

About_david_chapman

Sex machine

by: David A Chapman

April 18th, 2013 14:29

Today I learned there was a Ruby gem that could detect the gender of a name. The gem is called Sex Machine. It can even give geographical specific information on names. Check out my examples:

First you need to install it:

gem install sexmachine

Now you can detect genders based on a person's name like so:

require 'sexmachine'
 #=> true
sex_detector = SexMachine::Detector.new
 #=> matrix screen of text...
sex_detector.get_gender("David")
 #=> :male 
sex_detector.get_gender("Donna")
 #=> :female 
sex_detector.get_gender("Bob")
 #=> :male
sex_detector.get_gender("David", :norway)
 #=> :male 

Have fun!

So last week's post was similar to today. However, today I play with a bit more interesting RasPi libraries.

The big difference is that we're using software PWM via the wonderful pi-blaster library. It basically latches onto the DMA for the single PWM pin the RasPi offers, and gives you eight pins. It's derived from Richard Hirst's ServoBlaster but it allows a 100% duty cycle. We'll ultimately use this same library / concept to drive a remote controlled vehicle via drb with the Pi, but first things first!

Let's show some code.

The pi-blaster library expects that you send something like this to a device it creates for you:

echo "1=1" > /dev/pi-blaster

That would turn GPIO pin 1 on 100% of the time. The second argument is just a floating point number from 0 to 1.

I'm all about TDD, so I whipped up this spec for how my RGB LED object should work in Ruby:

describe RGBLed do
  it "can be instantiated with three GPIO pin numbers" do
    led = RGBLed.new(red_pin: 0, green_pin: 1, blue_pin: 2)
  end

  describe "setting color intensity" do
    before do
      @led = RGBLed.new(red_pin: 0, green_pin: 1, blue_pin: 2)
    end

    it "allows you to set red anywhere from 0 to 1" do
      @led.red = 1
      @led.red.must_equal 1
    end

    it "allows you to set green anywhere from 0 to 1" do
      @led.green = 1
      @led.green.must_equal 1
    end

    it "allows you to set blue anywhere from 0 to 1" do
      @led.blue = 1
      @led.blue.must_equal 1
    end

    it "does not allow you to set intensity above 1 or below 0" do
      lambda{ @led.red = 2  }.must_raise OutOfRangeException
      lambda{ @led.red = -1 }.must_raise OutOfRangeException
    end
  end

  describe "outputting pi-blaster commands" do
    before do
      @led = RGBLed.new(red_pin: 0, green_pin: 1, blue_pin: 2)
      @led.red   = 0.5
      @led.green = 0.75
      @led.blue  = 1
    end

    it "handles red" do
      @led.pi_blast_command(:red).must_equal "echo 0=0.5 > /dev/pi-blaster"
    end

    it "handles green" do
      @led.pi_blast_command(:green).must_equal "echo 1=0.75 > /dev/pi-blaster"
    end

    it "handles blue" do
      @led.pi_blast_command(:blue).must_equal "echo 2=1 > /dev/pi-blaster"
    end
  end
end

Then it was just a matter of making the spec work, so this class satisfies that spec:

class OutOfRangeException < StandardError; end

class RGBLed
  def initialize(options={})
    @options   = options
    @pins = {
      red:   fetch_option(:red_pin),
      green: fetch_option(:green_pin),
      blue:  fetch_option(:blue_pin)
    }
    @intensity = {
      red:   0,
      green: 0,
      blue:  0
    }
  end

  def red=(value)
    set_intensity(:red, value)
  end

  def red
    get_intensity(:red)
  end

  def green=(value)
    set_intensity(:green, value)
  end

  def green
    get_intensity(:green)
  end

  def blue=(value)
    set_intensity(:blue, value)
  end

  def blue
    get_intensity(:blue)
  end

  def pi_blast_command(channel)
    "echo #{get_pin(channel)}=#{get_intensity(channel)} > /dev/pi-blaster"
  end

  def pi_blast
    %w(red green blue).each do |c|
      `#{pi_blast_command(c)}`
    end
  end

  private
  def fetch_option(channel)
    @options.fetch(channel)  { raise "Must specify `#{channel.to_s}` option." }
  end

  def set_intensity(channel, value)
    validate_channel(channel)
    validate_intensity(value)
    @intensity[channel.to_sym] = value
  end

  def get_intensity(channel)
    validate_channel(channel)
    @intensity[channel.to_sym]
  end

  def get_pin(channel)
    validate_channel(channel)
    @pins[channel.to_sym]
  end

  def validate_channel(channel)
    return true if valid_channels.include?(channel.to_s)
    raise "Invalid attribute channel: #{channel}"
  end

  def validate_intensity(intensity)
    return true if valid_intensities.cover?(intensity)
    raise OutOfRangeException, "Invalid intensity: #{intensity}"
  end

  def valid_channels
    %w(red green blue)
  end

  def valid_intensities
    (0..1)
  end
end

As I mentioned in the video, the RGB LED we had on hand actually took ground to the channels, and positive voltage to the common pin, which went against my assumptions. Basically, setting red to 1 would mean off, and 0 would mean on. OOP is super-sweet, so this class fixes that up for me:

class InverseRGBLed < RGBLed
  def get_intensity(channel)
    1-super
  end
end

Finally (on the ruby side), we needed to expose him to the network. This script does that for me, as well as initializes him to blue.

require_relative '../lib/inverse_rgb_led.rb'

led = InverseRGBLed.new(red_pin: 0, green_pin: 1, blue_pin: 4)
led.pi_blast

led.red=0
led.green=0
led.blue=1
led.pi_blast

require 'drb/drb'
require 'pi_piper'

# The URI for the server to connect to
URI="druby://192.168.1.76:8787"

# The object that handles requests on the server
FRONT_OBJECT=led

$SAFE = 1   # disable eval() and friends

DRb.start_service(URI, FRONT_OBJECT)
# Wait for the drb server thread to finish before exiting.
DRb.thread.join

Then on the android side, this main activity will handle pretty much everything.

package com.isotope11.rgbledapp;

import java.util.ArrayList;
import java.util.List;

import org.jruby.embed.ScriptingContainer;

import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;

import com.commonsware.cwac.colormixer.ColorMixer;
import com.commonsware.cwac.colormixer.ColorMixer.OnColorChangedAndStoppedListener;

public class MainActivity extends Activity {

  protected final String TAG = MainActivity.class.toString();
  protected ScriptingContainer mRubyContainer;
  protected String mDrbResult;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    System.setProperty("jruby.bytecode.version", "1.5");
    mRubyContainer = new ScriptingContainer();
    List<String> loadPaths = new ArrayList<String>();
    loadPaths.add("jruby.home/lib/ruby/shared");
    loadPaths.add("jruby.home/lib/ruby/1.8");
    mRubyContainer.setLoadPaths(loadPaths);

    final Activity lol = this;

    ColorMixer colors = (ColorMixer) findViewById(R.id.mixer);
    colors.setOnColorChangedAndStoppedListener(new OnColorChangedAndStoppedListener() {
      @Override
      public void onColorChange(int argb) {
        int r = Color.red(argb);
        int g = Color.green(argb);
        int b = Color.blue(argb);
        RGBLedSetter task = new RGBLedSetter();
        task.setRed(r);
        task.setGreen(g);
        task.setBlue(b);
        task.execute();
      }
    });
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  private class RGBLedSetter extends AsyncTask<Object, Void, String> {

    int mRed = 0;
    int mGreen = 0;
    int mBlue = 0;

    @Override
    protected String doInBackground(Object... arg0) {
      String rubyDrbClient = "require 'drb/drb';SERVER_URI='druby://192.168.1.76:8787';DRb.start_service;led = DRbObject.new_with_uri(SERVER_URI);led.red=" + getMapped(mRed) + ";led.green=" + getMapped(mGreen) + ";led.blue=" + getMapped(mBlue) + ";led.pi_blast;";
      mRubyContainer.runScriptlet(rubyDrbClient);
      return "nope";
    }

    @Override
    protected void onPostExecute(String result){
      mDrbResult = result;
    }

    public void setBlue(int val){
      mBlue = val;
    }
    public void setGreen(int val){
      mGreen = val;
    }
    public void setRed(int val){
      mRed = val;
    }
    public String getMapped(int val){
      float newVal = Float.valueOf(val) / Float.valueOf(255);
      Log.d(TAG, Float.toString(newVal));
      return Float.toString(newVal);
    }
  }
}

If you are interested, here are some references:

About_josh_adams

Linkdump of Awesome Stuff #21

by: Josh Adams

April 12th, 2013 09:49

OCTOPUS IS WORKING

Ton of links today...

That's all I've got for now. Expecting to have a fun post later today as well...

So I got a bit more involved after my experiments last week.

This week I did the following:

  • Got the LED Toggler Ruby script from last week exposing a toggle-able LED object over the network with drb under MRI on the Raspberry Pi.
  • Built an Android app.
  • Inside of that Android app I embedded a JRuby ScriptingContainer.
  • In that ScriptingContainer I evaluated some ruby.
  • In that ruby script I connected to the aforementioned drb object.
  • On button press in the Android app, I call the #toggle method of the drb object.

This all combines to have the effect of an android app to toggle an LED on the network. This is, of course, extremely awesome and extensible. See the video above for proof.

The code for these things is available here:

I'll also just put the relevant bits of code in the post here:

server.rb

require 'drb/drb'
require 'pi_piper'

# The URI for the server to connect to
URI="druby://192.168.1.76:8787"

class Toggler
  attr_accessor :pin, :state

  def initialize
    @pin = PiPiper::Pin.new(pin: 15, direction: :out)
    @state = false
  end

  def toggle
    state ? pin.on : pin.off
    @state = !state
    puts 'toggled'
  end
end

# The object that handles requests on the server
FRONT_OBJECT=Toggler.new

$SAFE = 1   # disable eval() and friends

DRb.start_service(URI, FRONT_OBJECT)
# Wait for the drb server thread to finish before exiting.
DRb.thread.join

MainActivity.java

package com.isotope11.ledclicker;

import java.util.ArrayList;
import java.util.List;

import org.apache.bsf.BSFException;
import org.jruby.embed.ScriptingContainer;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

public class MainActivity extends Activity {

  protected final String TAG = MainActivity.class.toString();
  protected ScriptingContainer mRubyContainer;
  protected String mDrbResult;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    System.setProperty("jruby.bytecode.version", "1.5");
    mRubyContainer = new ScriptingContainer();
    List<String> loadPaths = new ArrayList<String>();
    loadPaths.add("jruby.home/lib/ruby/shared");
    loadPaths.add("jruby.home/lib/ruby/1.8");
    mRubyContainer.setLoadPaths(loadPaths);
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
  }

  public void onLEDClickerClick(View view) {
    RubyRunner rubyRunner = new RubyRunner();
    rubyRunner.execute();
  }

  public void handleDrbResult() {
    Toast.makeText(this, mDrbResult, Toast.LENGTH_LONG).show();
  }

  private class RubyRunner extends AsyncTask<Object, Void, String> {

    @Override
    protected String doInBackground(Object... arg0) {
      String rubyDrbClient = "require 'drb/drb';SERVER_URI='druby://192.168.1.76:8787';DRb.start_service;toggler = DRbObject.new_with_uri(SERVER_URI);toggler.toggle";
      String result = (String) mRubyContainer.runScriptlet(rubyDrbClient);
      return result;
    }

    @Override
    protected void onPostExecute(String result){
      mDrbResult = result;
      handleDrbResult();
    }

  }
}
About_josh_adams

Linkdump of Awesome Stuff #20

by: Josh Adams

April 5th, 2013 07:55

Yup

Here's a video Seth shared re: impressive ruby productivity with tmux and vim

About_josh_adams

Linkdump of Awesome Stuff #19

by: Josh Adams

March 29th, 2013 17:37

Links are so close......but first watermelon cat.

watermelon cat

And if you watch one video this week, let it be Guy Steele's Growing a Language:

About_josh_adams

Twitter + RasPi + Ruby + GPIO

by: Josh Adams

March 28th, 2013 23:00

So had to continue the last post. Here's an LED that turns on when you tweet at it :)

[UPDATE 2] So if you like this, you'll probably like the post where I integrate with an android app.

[UPDATE] I went a bit further, integrated the sucker with twitter.

So we used pi_piper just now to control some GPIO pins on our Raspberry Pi.

Good fun was had all around. It's also sitting in a 3d printed case because duh.

[UPDATE] I went a little further here and got Twitter involved.