Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: bb98593949e9
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 79a9581fccaa
Choose a head ref
  • 4 commits
  • 3 files changed
  • 4 contributors

Commits on Aug 14, 2015

  1. Add direct BubbleBabble power from OpenSSH

    cheald authored and kares committed Aug 14, 2015
    Copy the full SHA
    679b2e3 View commit details
  2. Copy the full SHA
    80c3599 View commit details
  3. Fix Digest bubblebabble incorrect output on empty string

    Before:
    
    bin/jruby -rdigest -e "p Digest.bubblebabble ''"
    "xx"
    
    After:
    
    bin/jruby -rdigest -e "p Digest.bubblebabble ''"
    "xexax"
    kubum authored and kares committed Aug 14, 2015
    Copy the full SHA
    532fa14 View commit details
  4. make require 'digest/bubblebabble' work (MRI compatibility)

    ... Digest.bubblebabble is being defined on require 'digest'
    kares committed Aug 14, 2015
    Copy the full SHA
    79a9581 View commit details
81 changes: 81 additions & 0 deletions core/src/main/java/org/jruby/ext/digest/BubbleBabble.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package org.jruby.ext.digest;

import org.jruby.util.ByteList;

/**
* Ported from OpenSSH (https://github.com/openssh/openssh-portable/blob/957fbceb0f3166e41b76fdb54075ab3b9cc84cba/sshkey.c#L942-L987)
*
* OpenSSH License Notice
*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved.
* Copyright (c) 2010,2011 Damien Miller. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

public class BubbleBabble {

public static ByteList bubblebabble(byte[] message, int begin, int length) {
char[] vowels = new char[]{'a', 'e', 'i', 'o', 'u', 'y'};
char[] consonants = new char[]{'b', 'c', 'd', 'f', 'g', 'h', 'k', 'l', 'm',
'n', 'p', 'r', 's', 't', 'v', 'z', 'x'};

int seed = 1;

ByteList retval = new ByteList();

int rounds = (length / 2) + 1;
retval.append('x');
for (int i = 0; i < rounds; i++) {
int idx0, idx1, idx2, idx3, idx4;

if ((i + 1 < rounds) || (length % 2 != 0)) {
idx0 = (((((int) (message[begin + 2 * i])) >> 6) & 3) + seed) % 6;
idx1 = (((int) (message[begin + 2 * i])) >> 2) & 15;
idx2 = ((((int) (message[begin + 2 * i])) & 3) + (seed / 6)) % 6;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
if ((i + 1) < rounds) {
idx3 = (((int) (message[begin + (2 * i) + 1])) >> 4) & 15;
idx4 = (((int) (message[begin + (2 * i) + 1]))) & 15;
retval.append(consonants[idx3]);
retval.append('-');
retval.append(consonants[idx4]);
seed = ((seed * 5) +
((((int) (message[begin + 2 * i])) * 7) +
((int) (message[begin + (2 * i) + 1])))) % 36;
}
} else {
idx0 = seed % 6;
idx1 = 16;
idx2 = seed / 6;
retval.append(vowels[idx0]);
retval.append(consonants[idx1]);
retval.append(vowels[idx2]);
}
}
retval.append('x');

return retval;
}
}
25 changes: 21 additions & 4 deletions core/src/main/java/org/jruby/ext/digest/RubyDigest.java
Original file line number Diff line number Diff line change
@@ -16,7 +16,7 @@
* Copyright (C) 2007 Nick Sieger <nicksieger@gmail.com>
* Copyright (C) 2008 Vladimir Sizikov <vsizikov@gmail.com>
* Copyright (C) 2009 Joseph LaFata <joe@quibb.org>
*
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
@@ -154,6 +154,11 @@ public static IRubyObject s_hexencode(IRubyObject recv, IRubyObject arg) {
return toHexString(recv.getRuntime(), arg.convertToString().getBytes());
}

@JRubyMethod(name = "bubblebabble", required = 1, meta = true)
public static IRubyObject bubblebabble(IRubyObject recv, IRubyObject arg) {
final ByteList bytes = arg.convertToString().getByteList();
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(bytes.unsafeBytes(), bytes.begin(), bytes.length()));
}

private static class Metadata {

@@ -326,6 +331,12 @@ public static IRubyObject hexdigest_bang(ThreadContext ctx, IRubyObject self) {
return toHexString(ctx.runtime, digest_bang(ctx, self).convertToString().getBytes());
}

@JRubyMethod(name = "bubblebabble", required = 1, optional = 1, meta = true)
public static IRubyObject bubblebabble(ThreadContext ctx, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
byte[] digest = recv.callMethod(ctx, "digest", args, Block.NULL_BLOCK).convertToString().getBytes();
return RubyString.newString(recv.getRuntime(), BubbleBabble.bubblebabble(digest, 0, digest.length));
}

@JRubyMethod()
public static IRubyObject to_s(ThreadContext ctx, IRubyObject self) {
return self.callMethod(ctx, "hexdigest");
@@ -349,7 +360,7 @@ public IRubyObject allocate(Ruby runtime, RubyClass klass) {
public DigestClass(Ruby runtime, RubyClass type) {
super(runtime, type);
}

@JRubyMethod(name = "digest", required = 1, rest = true, meta = true)
public static IRubyObject s_digest(ThreadContext ctx, IRubyObject recv, IRubyObject[] args, Block unusedBlock) {
Ruby runtime = recv.getRuntime();
@@ -394,7 +405,7 @@ public DigestBase(Ruby runtime, RubyClass type) {
if(metadata == null) {
throw runtime.newNotImplementedError("the " + type + "() function is unimplemented on this machine");
}

try {
setAlgorithm(metadata);
} catch(NoSuchAlgorithmException e) {
@@ -444,7 +455,7 @@ public IRubyObject finish() {
algo.reset();
return digest;
}

@JRubyMethod()
public IRubyObject digest_length() {
return RubyFixnum.newFixnum(getRuntime(), algo.getDigestLength());
@@ -465,6 +476,12 @@ public IRubyObject reset() {
return this;
}

@JRubyMethod()
public IRubyObject bubblebabble(ThreadContext context) {
final byte[] digest = algo.digest();
return RubyString.newString(context.runtime, BubbleBabble.bubblebabble(digest, 0, digest.length));
}

private void setAlgorithm(Metadata metadata) throws NoSuchAlgorithmException {
this.algo = createMessageDigest(getRuntime(), metadata.getName());
this.blockLength = metadata.getBlockLength();
1 change: 1 addition & 0 deletions lib/ruby/shared/digest/bubblebabble.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
require 'digest' # bubblebabble gets in with Digest ext loading