Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Participants: Ben Allen * Stephanie August * Damon Loren Baker * Theo Ellin Ballew * Ivette Bayo Urban * John Bell * Paisley Benaza * Kathi Berens * David Berry * Sayan Bhattacharyya * Christina Boyles * Gregory Bringman * André Brock * Ron Burkey * Evan Buswell * Sarah Ciston * Eileen Clancy * Tara Conley * Krystal Cooper * Ranjodh Dhaliwal * Anthony Di Franco * Craig Dietrich * Jeremy Douglass * Kevin Driscoll * William Dyson * Brandee Easter * Martin Erwig * Schuyler Esprit * Max Feinstein * Todd Furmanski * Geoffrey Gimse * Erin Glass * Rochelle Gold * Catherine Griffiths * Ben Grosser * Fox Harrell * Sydette Harry * Brendan Howell * Nazua Idris * Jessica Johnson * Waliya Yohanna Joseph * Ted Kafala * Dorothy Kim * Corinna Kirsch * Steve Klabnik * Shelly Knotts * Peter Kudenov * Fidelia Lam * Liz Losh * Thor Magnusson * Jim Malazita * Judy Malloy * Zach Mann * Mark Marino * Lauren McCarthy * Irma McClaurin * Patrick McDonnell * Tara McPherson * Todd Milstein * Nick Montfort * Mark Neal * Safiya Noble * Keith O'Hara * David Ogborn * Allison Parrish * Ali Pearl * Gerol Petruzella * Andrew Pilsch * Samuel Pizelo * Jessica Pressman * Helen Pritchard * Daniel Punday * Kristopher Purzycki * Harvey Quamen * Amit Ray * Margaret Rhee * Lisa Rhody * Scott Richmond * Teddy Roland * Jamal Russell * Anastasia Salter * Mark Sample * Evan Schauer * Ari Schlesinger * Mehdy Sedaghat Payam * Ash Smith * Winnie Soon * Glen Southergill * Mel Stanfill * Samara Hayley Steele * Nikki Stevens * Tonia Sutherland * Miriam Sweeney * Ezra Teboul * Daniel Temkin * Dennis Tenen * Marilyn M. Thomas-Houston * Elizabeth Timbs * Giuseppe Torre * Rebecca Uliasz * Annette Vee * Sneha Veeragoudar * Ashleigh Wade * Kurt James Werner * Jacque Wernimont * Zach Whalen * Roger Whitson * Roger Whitson * Michael Widner * Jody Zellen * Kai Zhang
Coordinated by Mark Marino (USC), Jeremy Douglass (UCSB), Catherine Griffiths (USC), Ali Rachel Pearl (USC), and Teddy Roland (UCSB). Sponsored by the Humanities and Critical Code Studies Lab (USC), and the Digital Arts and Humanities Commons (UCSB).

Week 2: Rando by Ben Grosser (Code Critique)

To round out this week on Critical and Creative Coding, we offer code from a Facebook app called Rando by artist Ben Grosser (@grosser). Like his Demetricator, the piece is part of Grosser's larger project to disrupt Facebook's control of its users.

In Ben's words:

Facebook’s “reactions” let you quickly express how you feel about a link, photo, or status. While such data might be helpful for your friends, these recorded feelings also enable increased surveillance, government profiling, more targeted advertising, and emotional manipulation. Go Rando is a web browser extension that obfuscates how you feel. Every time you click “Like”, Go Rando randomly chooses one of the six Facebook “reactions” for you. Over time you'll appear to Facebook’s algorithms as someone whose feelings are perfectly balanced—as someone who feels Angry as much as Haha or Sad as much as Love. You can still choose a specific reaction if you want to, but even that choice will be obscured by an emotion profile increasingly filled with noise. In other words, Facebook won’t know if your reaction was genuine or not. Want to see what Facebook feels like when your emotions are obscured? Then Go Rando!

Consider Rando in the context of the Week 2 theme.

Language: Javascript
Author: Ben Grosser

// ==UserScript==
// @name Go Rando
// @version 1.0.0
// @author Benjamin Grosser
// @namespace com.bengrosser.gorando
// @description Obfuscates your feelings on Facebook.

// @updateURL http://bengrosser.com/share/gr/go-rando.meta.js
// @downloadURL https://bengrosser.com/share/gr/go-rando.user.js
//
// @match *://*.facebook.com/*
// @include *://*.facebook.com/*
// @exclude *://*.facebook.com/ai.php*
// @exclude *://*.facebook.com/ajax/*
// @exclude *://*.facebook.com/dialog/*
// @exclude *://*.facebook.com/connect/*
// @exclude *://*.facebook.com/plugins/*
// @exclude *://*.facebook.com/xti.php*
//
// @icon http://bengrosser.com/share/gr/go-rando-logo-256.png
//
// ==/UserScript==// -----------------------------------------


// ******************************************
//
// Ben Grosser
//
// Go Rando
// 2017
// web browser extension
//
// (Started March, 2016 -- Released February, 2017)
//
// Premiere Exhibition:
// Blinding Pleasures
// Arebyte Gallery
// London, UK
// 10 Feb - 18 Mar, 2017
//
// Obfuscates your feelings on Facebook
// http://bengrosser.com/projects/go-rando/
//
// Thanks to my Beta Test Team!!
// --Janelle Gunther
// --Owen Mundy
// --Raphaël Duracell
//
// Thanks to Sebastian Frith for his Illustrator prowess!
//
// Big thanks to Kate McDowell, who suggested "Rando" as part 
// of the title!
//
// And special thanks to Filippo Lorenzin, curator of the 
// Blinding Pleasures exhibition, for all his help and support 
// for this work!
//
//
//
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⢀⠠⠨⢀⠈⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠐⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢈⠀⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠠⠠⢙⣿⣿⣿⣿⣿⣿⢉⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠠⢐⣿⠀⠀⣿⣿⣿⣿⣿⢐⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠁⡟⣿⣿⠠⠠⠠⠠⠀⠀⠀⠀
// ⠀⠀⠀⠈⠠⢘⣿⣿⣿⣿⣿⣿⣿⣿⢲⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠁⣿⣿⣿⠀⠀⠀⣿⢐⠠⠠⠠⠠⠀⠀⠀
// ⠀⠀⢀⠠⠠⠠⠠⢰⣿⠀⠀⠀⠀⠀⠀⡓⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⣿⣿⠀⠀⠀⣿⣿⣿⢢⠠⠠⠠⠠⠠⠠⠠⠀⠀
// ⠀⠀⠠⠠⠠⠠⠠⣏⣿⠀⠀⠀⠀⠀⠀⣿⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠫⣿⣿⣿⠀⠀⠀⣿⣿⣿⢈⢀⢀⠠⠠⠠⠀⠀
// ⠀⠠⠠⠠⠠⠠⢘⡍⣿⠀⠀⠀⠀⠀⣿⢉⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢐⡍⣿⣿⣿⠀⣿⢰⠈⠈⠐⠠⠠⠠⠀
//  ⠠⠠⠠⠠⠠⢈⠠⣆⣿⠀⠀⣿⣿⢘⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢈⠠⠠⠠⠠⠁⣿⣿⣿⣿⠁⢈⠁⠠⠈⠈⠠⠠⠠⠠⢀
//  ⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⠨⢐⠰⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢘⠠⠠⠠⠠⠹⣿⠀⠀⠀⠀⣿⢍⠠⢰⣿⣿⠰⢘⠠⠠⠰
// ⠀⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢈⢈⠠⠨⢈⠠⠠⠠⠠⠠⠠⠠⠠⢐⠠⠠⠠⠠⢈⡃⠀⠀⠀⠀⠀⠀⣿⣿⠀⠀⣿⢬⠰⠠⠠⠀
// ⠀⠠⠠⠠⠠⠠⠠⠠⠠⠠⠠⢈⢈⢈⠂⠠⠠⠠⠠⠠⠠⠠⠠⢈⠨⢼⣿⣿⠀⣿⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⠺⠰⢈⠠⠠⠠⠀
// ⠀⠀⠠⠠⠠⠠⠠⠠⠑⢩⢙⢩⣈⣈⢙⢙⢙⢙⢙⢙⢙⢙⢙⢈⠠⢨⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⣿⠨⢈⢐⠘⢈⠠⠠⠠⠀⠀
// ⠀⠀⠈⠠⠠⠠⠠⡤⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⠠⠠⠠⠠⢘⢈⠠⠙⣿⣿⣿⣿⢘⠠⠠⠠⠠⠠⠠⠠⢀⠀⠀
// ⠀⠀⠀⠀⠠⠠⠠⢠⣿⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⣿⣿⣿⠿⢈⠠⠠⢈⠨⠠⠠⠹⣿⠓⠠⠠⠠⠠⢀⠀⠀⠀
// ⠀⠀⠀⠀⠠⠠⠠⠠⢘⣿⠀⠀⠀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⣿⣍⠠⠠⠠⠠⠽⣿⣿⣿⢑⠠⠠⠠⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠠⠠⠠⠠⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⢌⢘⠠⠠⡡⣿⣿⢘⠠⠠⠠⡇⣿⣿⣿⣿⣿⢴⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠠⠠⠠⠠⠩⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡈⠠⠠⠠⠠⠠⠠⠠⠠⠠⣠⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠠⠠⠠⠋⣿⣿⣿⣿⣿⣿⣿⣿⡈⠠⠠⠠⠠⠠⠠⠠⠠⠙⣿⣿⣿⣿⣿⣿⣿⣿⢰⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠠⠠⢀⠠⠉⢔⠾⡓⡖⠨⠠⠠⠠⠠⠠⠠⠠⠠⠠⣿⣿⣿⣿⣿⣿⣿⣿⢈⠀⠀⠀⠀⠀
// ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣿⠀⠀⠀⠀⠀⠨⣞⣏⢷⠀⠀⠀⠀⠀⠀⠀⠀⠀
//
//
// ************************************************************


var j;
var IS_SAFARI_OR_FIREFOX_ADDON = true;
var LIKE_BLOCK_PARENT = '._khz';
var VERSION_NUMBER = '1.0.0';
var attaching = false;
var LANG = "en";

var reactionLabelsEN = ["Like","Love","Haha","Wow","Sad","Angry"];
var reactionLabelsFR = ["J’aime","J’adore","Haha","Wouah","Triste","Grrr"];
var reactionLabelsDE = ["Gefällt mir","Love","Haha","Wow","Traurig","Wütend"];
var reactionLabelsES = ["Me gusta","Me encanta","Me divierte","Me asombra","Me entristece","Me enoja"];
var reactionLabelsPT = ["Curtir","Amei","Haha","Uau","Triste","Grr"];
var reactionLabelsIT = ["Mi piace","Love","Ahah","Wow","Sigh","Grrr"];

var pickingTextEN = "Picking...";
var pickingTextFR = "Sélection...";
var pickingTextDE = "Auswählen...";
var pickingTextES = "Selección...";
var pickingTextPT = "Seleção...";
var pickingTextIT = "Selezione...";


function main() {
    var startURL = window.location.href;

    // Firefox/Safari Extensions/Userscripts don't allow 
    // excludes in the URL match, so we do it here.
    if(IS_SAFARI_OR_FIREFOX_ADDON) {
        if(startURL.contains("ai.php") || 
           startURL.contains("/ajax/") ||
           startURL.contains("/dialog/") ||
           startURL.contains("/connect/") ||
           startURL.contains("/plugins/") ||
           startURL.contains("/xti.php")
           ) return; 
    }

    // console reporting
    console.log("Go Rando "+VERSION_NUMBER);
    console.log("    --> "+startURL);

    // setup jQuery on j to avoid any possible conflicts
    j = jQuery.noConflict();

    // determine language. 
    LANG = j('html').attr('lang');

    if(!(LANG == "en" || LANG == "fr" || LANG == "de" ||
         LANG == "es" || LANG == "pt" || LANG == "it")) {
        console.log("Go Rando --> unsupported language detected ("+LANG+")"); 
        console.log("Go Rando --> defaulting to English");
        LANG = "en";
    }

    // monitor the DOM for insertions
    var watchNode = document.querySelector('body, ._5pcb');

    var observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if(mutation.type == "childList" && !attaching) {
                attaching = true;

                for(var i = 0; i < 2000; i+=250) {
                    delayedSetup(i);
                }
            }
        });
    });

    observer.observe(watchNode, { childList: true } );

    // run a few times for each insertion to catch 
    // slower-loading nodes
    function delayedSetup(t) {
        setTimeout(function() {
            setupReactionsBlock(j(LIKE_BLOCK_PARENT));
            if(t == 1750) attaching = false;
        }, t);
    }
}

// find the correct Like buttons and attach an obfuscator
function setupReactionsBlock(n) {
    n.
        not('.reactionObfuscated').
        addClass('reactionObfuscated').
        find('.UFILikeLink').
        each(function() {
            attachReactionObfuscator(j(this));
        }
    );
}

// binds a function to every Like button so that a click
// triggers an obufscation rather than regular "Like"
function attachReactionObfuscator(n) {
    var reactionLabels;
    var likeText;
    var pickingText;

    if(LANG == "en") {
        reactionLabels = reactionLabelsEN;
        pickingText = pickingTextEN;
    } else if(LANG == "fr") {
        reactionLabels = reactionLabelsFR;
        pickingText = pickingTextFR;
    } else if(LANG == "de") {
        reactionLabels = reactionLabelsDE;
        pickingText = pickingTextDE;
    } else if(LANG == "es") {
        reactionLabels = reactionLabelsES;
        pickingText = pickingTextES;
    } else if(LANG == "pt") {
        reactionLabels = reactionLabelsPT;
        pickingText = pickingTextPT;
    } else if(LANG == "it") {
        reactionLabels = reactionLabelsIT;
        pickingText = pickingTextIT;
    }

    likeText = reactionLabels[0];

    n.click(function(e) { 

        var likeON = false;
        if(n.hasClass('UFILinkBright')) likeON = true; 

        if(!likeON) {

            var pick = Math.floor(Math.random() * reactionLabels.length);
            var r = reactionLabels[pick];
            var lp = n.parent();

            function setThinking(jn) {
                j(jn).hide();
                return j(jn)
                        .parent()
                        .prepend("<a class='gr_picking'>"+pickingText+"</a>")
                        .promise();
            }

            setThinking(j(this)).done(function() {
                setTimeout(function() {
                    var t = lp.find('._iuw[aria-label="'+r+'"]');

                    if(t.length) {
                        if(r != likeText) t.click();
                        lp.find('.UFILikeLink').show();
                        lp.find('.gr_picking').remove();
                    } 
                    else {
                        lp.find('.UFILikeLink').show();
                        lp.find('.gr_picking').remove();
                    }
                }, 500);
            });
        }
    });
}


//
// ALL UTILITY BELOW HERE
//

// cleaner syntax than match()
String.prototype.contains = function(it) { return this.indexOf(it) != -1; };


// pasted jQuery 3.1.1 slim minified from 
// https://code.jquery.com/jquery-3.1.1.slim.min.js

See full code here.

Some starter questions:

-How does the code express Grosser's critical intervention?
-How does this code affect the way we see Facebook?
-In what ways does this code disrupt Facebook's functioning, serve or enhance it?
- Where do you sense Grosser's play and irony in the code?

Comments

  • Let's take something easy on the surface of the code, first. What do people make of the ASCII art of RANDO in the code itself. I know we've talked about this before, but what does it mean to put a depiction of the RANDO emoji (mult-emoji) into the code itself, how does that extend @grosser's subversion? How does the use of this 1980s art form, which has been reclaimed by retro artists, impact the way and what this code means?

  • Having just read some of the Hamilton papers, Rando reminds me of this passage about the in-flight manual reprogramming of Colossus:

    Of course, better can sometimes become the enemy of good. For example, lock mechanisms preventing human operators from entering an input error might also eliminate the possibility of fixing an unanticipated problem during a mission by going through the back door. On Apollo 14, for example, erroneous hardware signals were misleading the software, and it became necessary to manually intervene in real time to “fool” the software so that it would ignore the signals. The change, made at the eleventh hour by the developers working closely with the astronauts through Mission Control, would go against the software specification but would remain consistent with the original intent of the system requirements at large.

    Rando definitely "goes through the back door" -- riding on top of the FB page structure and injecting its own event handlers to "fool" the software into accepting different "signals." Rando also claims, like Hamilton's team hacking Collosus, to do so for the greater good, "go[ing] against the software specification ... [to] remain consistent with the original intent." (Whose intent?)

    Rando has to contend with quite a few more "lock mechanisms," however. We can't just re-key opcodes into Pinball. We have to rely on Google (/Mozilla/Apple) condoning extensions in the browsers, plus mediated "stores" to distribute them, key signatures, our trust that @grosser isn't malign, etc.

    And these "lock mechanisms" are distributed. Rando leads a very contingent life. It has to be less a program than a project, ready to change and adapt to the latest random changes to the FB page structure, to Google's extension API, to our expectations of privacy from @grosser, etc.

  • @markcmarino said:

    What do people make of the ASCII art of RANDO in the code itself. I know we've talked about this before, but what does it mean to put a depiction of the RANDO emoji (mult-emoji) into the code itself, how does that extend @grosser's subversion? How does the use of this 1980s art form, which has been reclaimed by retro artists, impact the way and what this code means?

    Encoding the RANDO emoticon-logo (by simulating dot-matrix printing using unicode braille, no less) is an interesting gesture. It is both "very 1980s" in its BBS-aesthetic, and at the same time absolutely 21st-century in two ways. First, it presumes a pervasive unicode infrastructure to make those codes legible (rather than ASCII) -- it isn't ASCII art, because it isn't using ASCII characters. Second, it is a play on the concept of emoji as they relate to mobile devices, social media and web 2.0+.

    I also feel like this is referential in a way that only works in relation to the original high-rez image. After a lot of squinting I guessed that it was a lopsided face with a huge tear-drop, rather than the planet earth with Australia leaking off the edge. But I wasn't confident in my guess. I think that the closure required to get to actual image (which is itself a compilation of other images) is more than you could expect character encoded art to accomplish. It works to evoke its referent only if you already know it.

    A final note: part of the play here is surely that many mixed / ambiguous / multi-faces are not part of standard emoticon character sets: the point of the RANDO logo is that it is a missing or imagined character -- something that doesn't exist in the constrained icon set, the provided characters or vocabulary.

Sign In or Register to comment.