Namen anonymisieren - irgendwie

16

Bearbeiten: Es gibt einen Bonus von -20 für zufällige Maskierung

Hallo Whistleblower-Kollegen und Träger von Geheimwissen.

Ich bin aufgrund eines Interviews per Mail und kann - natürlich - keine genauen Namen in voller Länge nennen. Aber da ich es auf eine nicht so offensichtliche Weise offenlegen möchte, brauche ich Ihre Hilfe.

Ich werde diese Namen in Form von angeben

"evil_company_that_makes_me_shiver"

aber ich will es doch nicht ganz ausdrücken. Ihre Aufgabe, mir und der ganzen Welt zu helfen, ist es, ein nettes Programm bereitzustellen, aus dem das oben Genannte wird

"ev**************************"

oder

"**il************************"

oder auch

"****_c**********************"

Ich denke du verstehst es. Aber es gibt einen Fehler: Ich möchte den Namen insgesamt offenlegen, daher muss ich die Anzahl der Vorkommen und das Wort selbst an das Skript weitergeben und die Buchstaben werden nach und nach offengelegt. Ein Beispiel könnte sein

~$ ./whistle NSA 3
> "N**"
> "**A"
> "*S*"

oder

~$ ./whistle nuclear 3
> "nu*****"
> "***lea*"
> "**c***r"

oder

~$ ./whistle nuclear 2
> "nuc****"
> "***lear"

Ich hoffe, Sie können mir helfen und da wir wissen, dass die Größe wichtig ist, gewinnt der kürzeste Code. Helfen Sie, diese Welt zu einem besseren Ort zu machen!

german_guy
quelle
1
Sie geben keine Details darüber an, wie die Maskierung erfolgen soll, daher sollten Sie unabhängig von Ihren Beispielen den kürzesten Code erhalten.
Bill Woodger
Ich dachte, es sei klar, dass der kürzeste Code gewinnt? Hmmm, vielleicht muss ich meine englische Grammatik danach verbessern :( / Edit: Es ist mir eigentlich egal, wie die Maskierung gemacht wird, das obige ist nur ein Beispiel, aber es sollte "unlesbar" sein, wenn Sie eine Akkordeon lesen Alleine "
german_guy
Ja, der kürzeste Code war klar. Meistens erhalten Sie jedoch eine "normale" Maskierung, die Ihren Proben nicht entspricht. Vielleicht sollten Sie, da es Ihnen sowieso nichts ausmacht, Ihre Sample-Ausgaben auf normale ändern. Speziell Ihr zweites Beispiel für die Ausführung sowie das Beispiel in Ihrer Frage
Bill Woodger
1
Oder Sie könnten einen Bonus für zufällige Maskierung.
ɐɔıɐɔu Aprs

Antworten:

12

GolfScript, 26 Zeichen

Da keine bestimmte Art der Offenlegung festgelegt wurde, habe ich mich für die kürzeste entschieden:

:f,\`{{\)f%.!@42if}%\;n}+%

Sie können mit diesem Code online experimentieren .

Beispiel:

> "ABCDEFGHIJKLMNOPQRSTUVWXYZ" 7
******G******N******U*****
*****F******M******T******
****E******L******S******Z
***D******K******R******Y*
**C******J******Q******X**
*B******I******P******W***
A******H******O******V****

Kommentierter Code:

:f           # Save the second input to variable f
,            # Makes the array [0 1 2 .... f-1]
\`{          # \´{}+% builds a code block where
             # first the input string is pushed (done
             # via the + operator and afterwards the whole
             # block is applied to above array, i.e.
             # For each line 0, 1, ...                                                
             #   Here, the stack contains the line number (counter)
             #   and the string
  {          #   {}% -> map to each character of the string
             #     Stack contains counter and current character
    \)f%     #     Increase the counter by one and calculate modulo f
    .        #     Duplicate counter (will be used for the if below)
    !        #     and test for zero 
             #     I.e. if counter==0
    @        #       Then Current character
    42       #       Else 42 (which is '*')
    if       #     
  }%         #   The mapping operation masked most of the characters
  \;         #   Discard the counter
  n          #   Add newline
}+%      
Howard
quelle
Nett! Können Sie erklären, was die einzelnen Teile des Codes bewirken?
John Odom
9
Kann nicht sehen warum. GolfScript ist so selbstdokumentierend.
Evpok
@JohnOdom Trotzdem habe ich einige Kommentare zum Code hinzugefügt.
Howard
Wenn Sie nach dem Zufallsprinzip entscheiden, ob Sie alle * s um eins nach rechts verschieben möchten oder nicht, zählt dies für den zufälligen Maskierungsbonus?
Cruncher
7

PHP - 80 Bytes

<?for(;($c=$argv[1][~-$i+=1])?:$k^++$j;)echo$c?$i%$k=&$argv[2]^$j?'*':$c:$i='
';

Beispielnutzung:

$ php whistle-blower.php ABCDEFGHIJKLMNOPQRSTUVWXYZ 7
******G******N******U*****
A******H******O******V****
*B******I******P******W***
**C******J******Q******X**
***D******K******R******Y*
****E******L******S******Z
*****F******M******T******
primo
quelle
7

Python ( 157 149 139 138-20 = 118):

def f(a,b):
 from random import*;c=[["*"]*len(a) for i in range(b)]
 for d in range(len(a)):choice(c)[d]=a[d]
 for e in c:print "".join(e)

Cheesy Python ( 55 35):

Du hast mir die benötigte Distribution nicht mitgeteilt;)

g=lambda a,b:["*"*len(a)]*(b-1)+[a]

Uniformpython ( 129 123 122):

def h(a,b):
 c=[["*"]*len(a)for i in range(b)]
 for d in range(len(a)):c=c[1:]+c[:1];c[0][d]=a[d]
 for e in c:print"".join(e)

Ausgabe:

a="Synthetica 'Evil' the Second"
b=7
f(a,b)
print
for i in g(a,b): print i
print
h(a,b)

gibt

***t***i***'***** *********d
******************t** ******
******t*** ***********Se**n*
S**************l****e*******
*y******c***E************o**
**n*h****a**************c***
*****e*******vi*'**h********

****************************
****************************
****************************
****************************
****************************
****************************
Synthetica 'Evil' the Second

******t******v******e******d
S******i******i****** ******
*y******c******l******S*****
**n******a******'******e****
***t****** ****** ******c***
****h******'******t******o**
*****e******E******h******n*
ɐɔıɐɔuʇǝɥʇs
quelle
Ihre kitschige Python kann auf gekürzt werden g=lambda a,b:[a]+["*"*len(a)]*(b-1). : P
cjfaure
@ Trimsty Ich verstehe, danke :)
--ıɐɔuʇǝɥʇs
3
Ich denke, aber ich möchte es sicherlich nicht ganz klar formulieren. Das macht eine Lösung ungültig, die nicht sicherstellt, dass in jeder Ausgabezeile mindestens ein Zeichen maskiert ist.
Howard
@Howard Ich weiß, dass es die Regeln übertrifft, disclose the letters bit by bitkann aber auch bedeuten first, disclose the first bit (that just happens to be the entire thing), repeat until the b is met. Dies kann auch bei der ersten Antwort der Fall sein. Behaupten Sie also, Sie haben diese Antwort verwendet, und es hat sich als nützlich erwiesen, dieses Ergebnis zu erzielen. (Mir ist gerade klar geworden, dass Sie es auch so schreiben können ["*"*len(a)]*(b-1)+[a], dass Sie zunächst Bits enthüllen, die zufällig 0 Byte tatsächliche Informationen enthalten, und in der letzten Zeile ein weiteres Bit.) Mir ist jedoch klar, dass dies der Fall ist dehnt sich auf die max.
ɐɔıɐɔu Aprs
3

Bash, 80 Bytes

m=${1//?/*}
for((i=1;d=i*${#1}/$2,i++<=$2;c=d)){
echo "${m:0:c}${1:c:d-c}${m:d}"
}

In Aktion:

$ ./anon.sh stackoverflow.com 6
st ***************
** ack ************
***** ove *********
******** rfl ******
*********** ow. ***
************** com
$ 
Digitales Trauma
quelle
2

C #, 226

Dies kann reduziert werden, wenn Sie das Zufallsmaterial durch eine einfachere Verteilung (Think Modulus) ersetzen, aber die Zufälligkeit hat mich interessiert. =)

Wie auch immer, wenn ich alles auf eine Zeile setze, bekomme ich 226 Zeichen. In lesbarem Code sieht es so aus:

private void F(string n, int i)
{
    var l = n.Length;
    var r = new Random();
    var a = new string[i];

    for (var p = 0; p < l; p++)
    {
        var x = r.Next(0, i);
        for (var j = 0; j < i; j++)
        {
            a[j] += j == x ? n.Substring(p, 1) : "*";
        }
    }

    for (var j = 0; j < i; j++)
    {
        Console.WriteLine(a[j]);
    }
}

Beispielausgabe:

Anonymize.exe ABCDEFGHIJKLMNOPQRSTUVWXYZ 7
*****F**I**********T**W***
A*****************S****X**
**CDE**H*JKL**************
*************N************
**************O*****U****Z
*B****G*****M***QR********
***************P*****V**Y*
deroby
quelle
Garantiert es immer mindestens Charakter von der Eingabe?
Bill Woodger
Hmm .. nein, wahrscheinlich nicht; guter Fang. Bei kurzen Saiten und niedrigen Werten ikönnte das wahrscheinlich enden ***/test.
Deroby
2

Perl, 24

$_ x=<>;s/(.|
)./\1*/g

Erfordert den -pSchalter, der zwei der Bytes ausmacht. Liest von STDIN.

Wie es funktioniert

  • Aufgrund des -pSchalters liest Perl die erste Eingabelüge und speichert ihren Inhalt in $_.

  • Der Befehl $_ x=<>;dupliziert die erste Eingabezeile so oft, wie in der zweiten Eingabezeile ( <>) angegeben.

  • Der Befehl benötigt s/(.|\n)./\1*/g;zwei Zeichen und ersetzt die zweite (die kein Zeilenumbruch sein darf) durch ein Sternchen. Es tut dies, bis es den gesamten Inhalt von verbraucht hat $_.

    Da Zeilenumbrüche als erstes Zeichen gezählt werden, werden alle geraden Zeichen in der ersten Zeile und alle ungeraden Zeichen in den verbleibenden Zeilen verschleiert.

  • Aufgrund des -pSchalters druckt Perl den Inhalt von $_.

Beispiel Eingabe

codegolf
4

Beispielausgabe

c*d*g*l*
*o*e*o*f
*o*e*o*f
*o*e*o*f
Dennis
quelle
doppelte Zeichenfolgen, nicht sehr sauber ...
CSᵠ
Warum hast du gedacht, du könntest mit der Eingabe herumspielen, um sie in zwei Zeilen zu haben?
Bill Woodger
@ BillWoodger: Die Frage gibt keine Form der Eingabe an.
Dennis
Meinetwegen. couldlässt dich durch :-)
Bill Woodger
Since newlines count as the first character, this will obfuscate all even characters on the first line and all odd characters on the remaining lines.Klingt so, als ob es fehlschlagen wirdcodegolf\n1
Cruncher
1

Java - 490

Ja, nicht wirklich golfen oder so. Na ja, hier ist es:

import java.util.ArrayList;public class Anonymise {public static void  main(String[] args){ArrayList[] c=new ArrayList[Integer.parseInt(args[1])];for(int i=0;i<c.length;i++)c[i]=new ArrayList();for(char a:args[0].toCharArray()){int f=new java.util.Random().nextInt(c.length);c[f].add(a);for(int i=0;i<c.length;i++)if(i!=f)c[i].add('*');}ArrayList<String> b = new ArrayList<String>();for(ArrayList a:c){String s = "";for(Object o : a)s += o;b.add(s);}for(String s : b)System.out.println(s);}}

In einem schönen, leserlichen Format:

import java.util.ArrayList;

public class Anonymise {

public static void main(String[] args){
    ArrayList[] c = new ArrayList[Integer.parseInt(args[1])];
    for(int i=0;i<c.length;i++)
        c[i]=new ArrayList();
    for(char a:args[0].toCharArray()){
        int f = new java.util.Random().nextInt(c.length);
        c[f].add(a);
        for(int i=0;i<c.length;i++)
            if(i!=f)c[i].add('*');
    }
    ArrayList<String> b = new ArrayList<String>();
    for(ArrayList a:c){
        String s = "";
        for(Object o : a)
            s += o;b.add(s);
    }
    for(String s : b)
        System.out.println(s);
}
}

Beispielnutzung (Bei Ausführung in der kompilierten Klasse)

> java Anonymise OnlinePerson 3
*n****P***o*
O*li***e****
****ne**rs*n
Isaac
quelle
Führen Sie das aus oder tippen Sie? Wie kommt P dazu, p zu sein?
Bill Woodger
Kein Problem. Nur die verwendeten Kommentare jetzt aufräumen
Bill Woodger
Gerade import java.util.*auch ArrayList<String> = new ArrayList<>();funktionieren wird. Sie können auch viele Leerzeichen entfernen. Und die meiste Zeit können Sie Liststatt verwenden ArrayList.
Ypnypn
1

Python 3 - 187 (-20 = 167)

Hat eine Weile gedauert um zu schreiben, könnte wohl mehr golfen werden.

import sys,random as a
b=sys.argv
x=[""for i in' '*int(b[2])]
for i in range(len(b[1])):n=a.randrange(len(x));x=[c+["*",b[1][len(c)]][j==n]for j,c in enumerate(x)]
for i in x:print(i)

Beispielnutzung:

$ python tx.py super_anonymous_user 3
s******n**y*ou****e*
**p***a**n*m**s_us*r
*u*er_**o***********

Als Funktion - 161 (-20 = 141)

from random import*
def f(c,n):
    x=[""for i in' '*n]
    for i in range(len(c)):n=randrange(len(x));x=[v+["*",c[len(v)]][j==n]for j,v in enumerate(x)]
    return x
cjfaure
quelle
Garantiert es immer mindestens Charakter von der Eingabe?
Bill Woodger
@ BillWoodger Nr.
cjfaure
2
Entschuldigung, ich persönlich halte es dann für nicht funktionierend. dann.
Bill Woodger
Einige einfache Möglichkeiten, um Dinge zu verkürzen: Entpacken Sie sys.argvdie Zuweisung und initialisieren Sie sie xals x=['']*int(b[2])(wobei b[2]die Variable, die Sie beim Entpacken verwenden, durch einen beliebigen Namen ersetzt wird).
user2357112 unterstützt Monica
2
Ich denke, aber ich möchte es sicherlich nicht ganz klar formulieren. Das macht eine Lösung ungültig, die nicht sicherstellt, dass in jeder Ausgabezeile mindestens ein Zeichen maskiert ist.
Howard
1

C # 184

namespace System.Linq{class P{static void Main(string[] a){int n=int.Parse(a[1]);for(int i=0;i<n;i++)Console.WriteLine(new String(a[0].Select((c,x)=>(i+x)%n==0?c:'*').ToArray()));}}}

Nicht golfen

namespace System.Linq
{
    class P
    {
        static void Main(string[] a)
        {
            int n = int.Parse(a[1]);
            for (int i = 0; i < n; i++)
                Console.WriteLine(new String(a[0].Select((c, x) => (i + x) % n == 0 ? c : '*').ToArray()));
        }
    }
}

Stichprobe:

> Anonymize.exe "qwertyuio" 4
q***t***o
***r***i*
**e***u**
*w***y***
Rik
quelle
1

Perl 6 (77 Bytes)

Dies kann als Betrug gewertet werden, löst jedoch das Problem (der String wird nicht vollständig gedruckt).

($_,$!)=@*ARGS;.say for .chop~"*","*"x.chars-1~.substr(*-1),"*"x.chars xx$!-2

Und die Beispielausgabe.

> ./script.p6 ultimately_awesome 6
ultimately_awesom*
*****************e
******************
******************
******************
******************
Konrad Borowski
quelle
1

JavaScript - 170

function s(a,e){o="",b=a.length,x=b/e|0,y=b-x*e;for(c=1;c<=e;c++){r="*";o+=Array((c-1)*x+1).join(r)+a.substr(c*x-x,c==e?x+y:x)+Array(c<e?b-c*x+1:0).join(r)+"\n"}return o}

Schnelle, bricht ab, wenn Sie einen Namen angeben und nach mehr Stücken als Zeichen fragen, funktioniert aber bis zu diesem Punkt und bis zu 1. Könnte, wie ich annehme, mehr Golf gespielt werden.

Bearbeiten: Golf weiter (ab 187) mit Entfernen der Klammern (@Synthetica) und Math.floor Ersatz von @toothbrush. Ein vorgeschlagener Schleifenwechsel führt zu Fehlern in der Ausgabe.

Matt
quelle
function s(d,a){o="";b=d.length;x=Math.floor(b/a);y=b-x*a;for(c=1;c<=a;c++)r="*",o+=Array((c-1)*x+1).join(r)+d.substr(c*x-x,c==a?x+y:x)+Array(c<a?b-c*x+1:0).join(r)+"\n";return o}; closure-compiler.appspot.com/home konnte 8 Zeichen absparen ;)
absparen
Wollen Sie damit sagen, dass der Text aus fünf Zeichen besteht und sechs Ersetzungen erfordert, die unterbrochen werden?
Bill Woodger
@ BillWoodger Er sagte, dass er mit dem Closure-Compiler 8 Zeichen von der Gesamtlänge des Codes entfernt habe.
Eduard Florinescu
@EduardFlorinescu, sorry, ich war unklar, ich meinte dies bisschenbreaks if you supply a name and ask for more pieces than characters
Bill Woodger
1
Verwenden Sie x=b/e|0anstelle von x=Math.floor(b/e). Auch for(c=1;c<=e;c++)kann auf gekürzt werden for(c=1;c++<=e;).
Zahnbürste
1

R, (120-20) = 100 Bytes (2 verschiedene Lösungen gleicher Länge)

Neben der Prägnanz bietet R mit Sicherheit den besten Zufallsgenerator! :) Hier die 1. Lösung der Länge 120:

function(s,n){
  c=strsplit(s,"")[[1]]
  e=sample(n,nchar(s),T)
  sapply(1:n,function(i)paste(ifelse(e==i,c,"*"),collapse=""))
}

Wenn die Funktion f heißt , sieht die Ausgabe folgendermaßen aus:

> f("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 7)
"******GH*****************Z" 
"ABCD*********N************" 
"***********L**O***********"
"*********J**M**P*RS*U**X**" 
"**********K***********W***" 
"*****F**I*******Q*********"
"****E**************T*V**Y*"

Und hier die 2. Lösung, wieder mit zufälliger Maskierung und wieder 120 Bytes lang:

function(s,n){
  x=matrix("*",n,(m=nchar(s)))
  x[cbind(sample(n,m,T),1:m)]=strsplit(s,"")[[1]]
  apply(x,1,paste,collapse="")
}
lambruscoAcido
quelle
0

Scala (1) 177 Bytes

Nachdem die Lösung in RI auch eine in Scala gefunden hat, ist es hier:

def f(s:String, n:Int)={
  def c=s map (z=>z.toString)
  def r=(1 to s.length) map (v=>v%n+1)
  (for (i<-1 to n) yield s zip r map (t=>if(t._2==i) t._1 else "*") mkString "") map println
}

Scala (2) 129 Bytes

Nach kurzer Recherche fand ich die Methode zipWithIndex . Wunderbar :)

def f(s:String, n:Int)={
  (for (i<-0 until n) yield s.zipWithIndex.map (t=>if(t._2 % n==i) t._1 else "*") mkString "") map println
}

Hier die Lösung:

f("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 4)
***D***H***L***P***T***X**
A***E***I***M***Q***U***Y*
*B***F***J***N***R***V***Z
**C***G***K***O***S***W***
lambruscoAcido
quelle
0

Javascript - 166

function s(b,a){o="";k=Array(a).join("*");t=k+b+k;for(i=a;0<i;i--)o+=t.replace(RegExp(".{"+(a-1)+"}(.)","g"),k+"$1").substr(i-1,b.length)+"\n",t=t.substr(1);return o}

Regex verwenden.

Stichprobe

> s("four",5)                      
f***                            
*o**                             
**u*                             
***r                             
****                             

> s("evil_company_that_makes_me_shiver",3)
e**l**o**a**_**a**m**e**m**s**v**
*v**_**m**n**t**t**a**s**e**h**e*
**i**c**p**y**h**_**k**_**_**i**r
zoro
quelle
0

k [50-20 = 30 Zeichen]

{.{@[y#"*";z;:;x z]}[x;c]'=_d*y%#d:<<(-d)?!d:c:#x}

Erläuterung

  1. Eingabe: x = String, der maskiert werden soll, y = Anzahl der Zeilen
  2. Zählen Sie die Anzahl der Zeichen c in string und erstellen Sie y Buckets.
  3. Platzieren Sie c mod y Zeichen in jedem Bucket.
  4. Geben Sie für jeden Eimer "*" für die verbleibenden Zahlen aus, die sich nicht in diesem Eimer befinden.

Beispiel

{.{@[y#"*";z;:;x z]}[x;c]'=_d*y%#d:<<(-d)?!d:c:#x}["abcdefghijklmnopqrstuvwxyz";4]

Ausgabe

"ab*d*f***j**********u*w***"
"**c*e*gh**k*****q*s*******"
"********i***mn*****t*v**y*"
"***********l**op*r*****x*z"
Nyi
quelle
0

JavaScript - 139-20 = 119

function e(s,c){r=[];for(i=c;i--;)r[i]='';for(i=0;i<s.length*c;i++)x=i%c,n=(x<1?Math.random()*c|0:n),r[x]+=(n!=x?'*':s[(i/c)|0]);return r}

Verwendung und Beispielausgabe:

console.log(e("evil_company_that_makes_me_shiver", 3));

["**i*_**mp*****h**_ma**********v**", 
 "*****co**a***t*a******s*me_*hi*e*", 
 "ev*l******ny_***t***ke*_***s****r"]

Da die Maskierung zufällig ist, kann die Ausgabe auch so aussehen:

console.log(e("evil_company_that_makes_me_shiver", 2));

["evil_company_that_makes_me_shiver", 
 "*********************************"]
codeporn
quelle
0

Julia 56-20 = 36 (arbeitet oft)

f(s,n)=[join([rand()<1.9/n?c:"*" for c in s]) for r=1:n]

julia> f("evilcompany!!!",4)
4-element Array{Union(UTF8String,ASCIIString),1}:
 "e**l**mp*ny*!*"
 "***lco********"
 "e*il**m*a*y!*!"
 "evil**m*an***!"

In dem Versuch, eine kürzere zufällige Lösung zu finden, habe ich beschlossen, die garantierte Funktion für eine kürzere Lösung zu opfern. Es ist wirklich keine sehr gute Lösung.

gggg
quelle
0

F # - 81 80 75

Dies ist ziemlich ähnlich zu anderen, die angeboten wurden:

let a s n=[for i in 0..n-1->String.mapi(fun j c->[c;'*'].[min((j+i)%n)1])s]

Stichprobe:

a "evil_company_that_makes_me_shiver" 7

e******m******h******e******h**** 
******o******t******k******s***** 
*****c******_******a******_****** 
****_******y******m******e******r 
***l******n******_******m******e* 
**i******a******t******_******v** 
*v******p******a******s******i*** 

Als vollständige, eigenständige Anwendung ergeben sich 160 155 156 Zeichen:

[<EntryPoint>]let m (a:string array)=
 let n=System.Int32.Parse a.[1]
 for i in 0..n-1 do printfn"%s"(String.mapi(fun j c->[c;'*'].[min((j+i)%n)1])a.[0])
 0
pswg
quelle