读取密码


20

您的挑战是从键盘/标准输入中读取“密码”。

挑战

  • s看不见字符串。
  • 对于其中的每个字符s,请打印一个字符c
  • 实时。

规则:

  • 您必须c实时打印。用户输入字符后,您必须立即显示c
  • c 必须为常数,即必须为相同字符。
  • c可以是任何可见字符(即不能是换行符,空格,制表符或不可打印的字符)。
  • c不能基于s,即c必须在s读取之前定义/常量。
  • c 每次运行程序时都必须相同。
  • cs只要遵守其他所有规则,就可以是其中的字符之一。
  • 除了之外,所有字符都不会s出现在屏幕上c(请参阅上一条规则)。
  • 您可以使用任何合理的输入和输出方法,只要遵循所有其他规则即可。
  • 您可以假设的长度s永远不会超过终端/图形窗口的宽度。
  • 如果使用终端,则应在输入换行符或EOF后终止程序。

范例

如果swas password01cwas *,输出将类似于:

password

优胜者

每种语言中提交时间最短的作品将获胜。


python是否tkinter允许使用我们的自定义输入字段(例如HTML中的),这样在按下Enter键时程序不会终止,但是在您关闭Entry“窗口”时(Windows 上为X,在Mac 上为cmd+ W)。
Xcoder先生17年

@ Mr.Xcoder是的,这是有效的。
MD XF

我们可以使用Ctrl + J代表终端中的文字换行符吗?或者,我们可以使用Ctrl + Z代替Enter吗?
Conor O'Brien

@ ConorO'Brien阐明输入应如何在终端中结束。
MD XF

2
如果用户按退格键该怎么办?
zdimension

Answers:



20

HTML,20个字节

<input type=password


备选:HTML + JavaScript,51字节

尽管OP已经确认这是有效的,但以下是使用JS的纯粹主义者的解决方案!

<input id=i oninput=i.value=i.value.replace(/./g,8)


4
FGITW,有人吗?:P(从字面上看是十秒钟)
MD XF

oninput=_=>i.value=i.value.replace(/./g,"*")保存一个字节。
Arjun

既然c可以做任何事情,您可以使用oninput=_=>i.value=i.value.replace(/./g,1)
Arjun

我担心的是,当有人宣布我的纯HTML解决方案无效时,@ Arjun;)我只会快速地将JS放在一起以安抚几个人!
毛茸茸的

6
解释在哪里,我听不懂。
Magic Octopus Urn

11

Vim,36个字节:

:im <C-v><CR> <C-v><esc>ZQ<CR>:au I<tab><tab> * let v:char=0<CR>i

这将使用VIM-键符号,所以<C-v>控制-V <CR>是进,<esc>是ESC键,并且<tab>是TAB键。

c'0'

这是一个十六进制转储来证明字节数是正确的:

00000000: 3a69 6d20 160a 2016 1b5a 510a 3a61 7520  :im .. ..ZQ.:au 
00000010: 4909 0920 2a20 6c65 7420 763a 6368 6172  I.. * let v:char
00000020: 3d30 0a69                                =0.i

这可以通过运行以下两个ex命令来实现:

:imap <CR> <esc>ZQ
:autocmd InsertCharPre * let v:char=0

第一个手段

:imap               " Anytime the following is pressed in insert mode:
      <CR>          "   (the 'enter' key)
           <esc>ZQ  " Then act as if the user instead pressed '<esc>ZQ' (close the buffer)

第二个是

:autocmd                                " Automatically as vim runs:
         InsertCharPre                  "   Any time the user is about to insert a char
                       *                "   In any type of file
                         let v:char=0   "     Then instead insert a '0' character

我认为没有一种方法可以使用我当前的方法来解决这个问题,而至少不能忽略空格。.不错的答案!
nmjcman101

o_O很好...
Xcoder先生


6

乙酰8 7 6个字节

,!`XpO

说明:

读取一个字符(,),取反它(!),然后有条件退出。将零打印在堆栈(p)的顶部,然后返回到开头。

与运行 -F立即看到效果(因为冲洗)

我的第一个解决方案是基于沙箱帖子,允许使用空格作为替换字符,而无需在回车时退出(4个字节):

,'p>

5

C对POSIX,128个 117 113 96字节

-11感谢Quentin搜索termios.h
-4,感谢Quentin指出了我的愚蠢错误
-17,因为Quentin是个疯狂的向导。

c,t[15];f(){for(tcgetattr(1,t),t[3]&=~10,tcsetattr(1,0,t);(c=getchar())^10&&c^4;)printf(".");}

这会将STDIN置于原始/不可见模式,以便可以实时获取按键。这需要77个字节,我敢肯定我可以打一下它。请注意,这不会在退出时重置STDIN,因此如果您不手动进行操作,则会使您的终端混乱。

重置STDIN的方法如下:

void stdin_reset(void)
{
    struct termios t;
    get_stdin(&t);
    t.c_lflag |= ECHO;
    t.c_lflag |= ICANON;
    set_stdin(&t);
}

输出如GIF所示:-)


1
挖掘我的termios.hECHO0000010ICANON0000002。这意味着,~(ECHO|ICANON)仅仅是~10:)
昆廷-

@Quentin编辑!干杯:D
MD XF

1
此外,每个!=可被替换^,并'\n'10);(假设UTF-8)
昆汀

2
如果我们使用了完整的UB,则可以用t整数数组代替的存储。然后c_lcflags以结尾t[3],我们不需要名称或类型,也不需要#include,总共94个字节:c,t[15];f(){for(tcgetattr(1,t),t[3]&=~10,tcsetattr(1,0,t);(c=getchar())^10&&c^4;)printf(".");}-但也许您最好让我将其发布为答案,而不是与您的乐趣:)
Quentin

1
@Quentin哦...我的。你是个向导。我认为我擅长C ...如果您愿意将它发布为自己的答案,请放回我的修改,否则我将其保留为我的修改。
MD XF

4

MS-DOS上的x86机器代码-14个字节

像往常一样,这是一个完整的COM文件,可以在DosBox以及大多数DOS变体上运行。

00000000  b4 08 b2 2a cd 21 80 f4  0a 3c 0d 75 f7 c3        |...*.!...<.u..|
0000000e

评论程序集:

    org 100h

section .text

start:
    mov ah,8h       ; ah starts at 08h (read console, no echo)
    mov dl,'*'      ; write asterisks (we could have left whatever
                    ; startup value we have here, but given that dx=cs,
                    ; we have no guarantee to get a non-zero non-space
                    ; value)
lop:
    ; this loop runs twice per character read: the first time with
    ; ah = 08h (read console, no echo syscall), the second time with
    ; ah = 02h (write console); a xor is used to switch from one
    ; mode to the other
    int 21h         ; perform syscall
    xor ah,0ah      ; switch syscall 08h <=> 02h
    cmp al,0dh      ; check if we read a newline (if we wrote stuff
                    ; we are just checking the last value read, so
                    ; no harm done; at the first iteration al starts
                    ; at 0, so no risk here)
    jne lop         ; loop if it wasn't a newline
quit:
    ret             ; quit

2
...没门。棒极了。
MD XF

谢谢,但是我觉得还有一些其他的事情要解决。这xor是一个woppin的3个字节,如果我使它整体上工作,它将完全一样大ax;我尝试过xor ax,0a0dh/ test al,al,但它也一样大,因为愚蠢的test是两个字节,grrr ...
Matteo Italia



3

爪哇5-8,125个 122 131 124字节

class X{public static void main(String[]a){new java.awt.Frame(){{add(new javax.swing.JPasswordField());setVisible(1>0);}};}}

取消高尔夫:

class X{
    public static void main(String[]a){
        new java.awt.Frame(){
            {
                add(new javax.swing.JPasswordField());
                setVisible(1>0);
            }
        };
    }
}

结果:

enter image description here

信用:

-3 @MD XF(指出我的愚蠢错误String[]args

-7 @KritixiLithos(指出public class可以是class


1
String[]args必要吗?
MD XF

@MDXF如果我想为Java 8做出答案,我可以做很多事情。但是,我正在将其作为通用Java答案。但是,是的,我可以做到这一点String[]a
Magic Octopus Urn

您忘记更新打高尔夫球的答案了。另外,不1>0等于1
MD XF

@MDXF在Java (< 8)- 1>0的计算结果为true,这是不同的。我将在Groovy中发布相同的答案。
Magic Octopus Urn

@StephenS这是一个通用的Java答案,而不是Java 8答案。
Magic Octopus Urn

3

Mathematica 34字节

 InputString["",FieldMasked->True];

键入每个字符后,将出现一个星号。空引号用于显示在弹出输入窗口中的标题。

所述;被印刷防止密码。

enter image description here


有意领导空间?
MD XF

2

Vim,58 50 52 50字节

添加以确保其正确处理了空格。

感谢@DJMcMayhem提供了许多帮助和想法

i:im 32 *Y94pVGg
kWcW<Space>
:im 
 ZQ
dG@"qi

在下面的典型Vim键语法中。用a标记的字符^Ctrl+<char>,所以^Q=Ctrl+q

i:im ^V^V32 *^[Y94pVGg^A
kWcW<Space>^[
:im ^V
 ZQ
dG@"qi

没有TIO链接,因为您需要直接输入到Vim(而不是像通常那样预先输入)。要运行代码,您需要将其输入Vim,然后可以输入密码并按Enter。密码不会做任何事情。它甚至不知道那是什么。按下后,立即进入Vim窗口:q!

通过*在插入模式下将所有可打印的ASCII 映射<CR>到,然后映射到<ESC>:q!<CR>


Maybe clarify what the symbols are? I think they're supposed to be <C-v>, <esc> and <C-a> but it's hard to tell.
DJMcMayhem

@DJMcMayhem Will do. Incidentally I think that you can paste them into Vim and they'll show up appropriately.
nmjcman101


2

FLTK, 47 characters

Function{}{}{Fl_Window{}{}{Fl_Input{}{type 5}}}

Sample run:

bash-4.4$ fluid -c password.fl

bash-4.4$ fltk-config --compile password.cxx 
g++ -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/freetype2 -I/usr/include/cairo -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -fvisibility-inlines-hidden -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_THREAD_SAFE -D_REENTRANT -o 'password' 'password.cxx' -Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -lfltk -lX11

bash-4.4$ ./password 

Sample output:

password input in FLTK


2

Processing, 53 bytes

String a="";void draw(){text(keyPressed?a+=0:a,9,9);}

This takes input via keypresses from a graphical window. The character it chooses to represent passwords with is 0. Note that due to the high framerate, each keypress will appear as multiple 0s (and also due to the fact that this is keyPressed and not keyTyped (not a boolean) or keyrelease).

gif


2

Bash, 54 bytes

while read -eN1 c 2>&-;[[ ${c/$'\r'/} ]];do printf X;done

For scoring purposes, $'\r' can be replaced with a literal carriage return.

Try it online! (not much to look at)


2

ZX81 BASIC, 54 bytes

10 IF LEN INKEY$ THEN GOTO PI
30 IF NOT LEN INKEY$ THEN GOTO EXP PI
50 IF INKEY$>"Z" THEN STOP
70 PRINT "*";
90 GOTO PI

In the ZX81 character set the printable characters are in the range space to Z, although you can't actually input a space this way as it's the break character.

ZX Spectrum BASIC, 24 bytes

10 PAUSE NOT PI: IF INKEY$>=" " THEN PRINT "*";:GOTO PI

Note that >= counts as a single-byte keyword in Sinclair BASIC (codepoint 140 in this case).


Are the spaces between the line numbers and functions necessary?
MD XF

Could you shorten PRINT to ?, I know that works in a lot of old BASIC dialects
MD XF

@MDXF PRINT is a 1-byte token, it's just represented on screen as the 7 characters (except after THEN, when the leading space is suppressed).
Neil

2

R, 29 bytes

invisible(openssl::askpass())

Built-in that handles password entries. Opens a new window and replaces the input with dots. invisible is used to suppress printing the password to STDOUT.


2

Tcl/Tk, 18

gri [ent .e -sh *]

Must be run on the in the interactive shell (or have abbreviations enabled):

enter image description here


21 bytes without the tricky command abbreviations: grid [entry .e -sh *] and -sh is an option abbreviation for -show. 23 bytes is what I'd consider a minimum for a maintainable ungolfed program doing this.
Donal Fellows

2

Vim, 15 keystrokes

:cal inp<S-tab>'')|q<cr>

<S-tab> means shift + tab.

Apparently, there is a builtin for this that I wasn't aware of. Since I really like my manual answer, and this approach is radically different, I figured I should post a new answer instead of editing.

This works by calling the inputsecret function, then immediately quitting after it exits.


2

6502 machine code (C64), 22 21 bytes

0e 08 20 9f ff 20 e4 ff f0 f8 c9 0d f0 01 a9 60 20 d2 ff 50 ed

Usage: SYS 2062

Commented disassembly listing (ACME), you can uncomment the first three commented lines to launch with RUN once loaded:

!cpu 6502
!to "password2.prg",cbm
;* = $0801                               ; BASIC starts at #2049
;!byte $0d,$08,$dc,$07,$9e,$20,$32,$30   ; BASIC to load $c000
;!byte $36,$32,$00,$00,$00               ; inserts BASIC line: 2012 SYS 2062

    GETIN  =  $FFE4
    SCNKEY =  $FF9F
    CHROUT =  $FFD2

* = $080e
keyScan:
    jsr SCNKEY  ; get key
    jsr GETIN   ; put key in A

    beq keyScan ; if no key pressed loop    

    cmp #13     ; check if RETURN was pressed
    beq $081b   ; if true go to operand of next instruction (#$60 = rts)

    lda #$60    ; load char $60 into accumulator
    jsr CHROUT  ; print it

    bvc keyScan ; loop

Comments:

  • I haven't found anything in the docs, but it seems that, after the GETIN call, beq branches only where no new key presses have been recorded;
  • Using #$60 as output char, that byte can be reused as "rts" instruction when RETURN is pressed.

2

Forth (gforth), 54 bytes

: f begin key dup 4 - swap 13 - * while ." *" repeat ;

Explanation

begin      \ enters the loop
    key    \ waits for a single character as input, places ascii code of character on stack
    dup    \ duplicates the key value on the stack
    4 -    \ subtracts 4 from the key value (shorter way of checking for not equals)
    swap   \ swaps the top two stack values
    13 -   \ subtract 13 from the key value
    *      \ multiply top two stack values (shorter version of "and")
while      \ if top of stack is true, enter loop body, else exit loop
    ." *"  \ output *
repeat     \ go back to beginning of loop

1

Python 3 + tkinter - 63 61 bytes

from tkinter import*
t=Tk();Entry(show=1).pack();t.mainloop()

Displays a 1 for every character, ends when closing window (OP said it's allowed).

Gif


Would from tkinter import* (newline) Entry(show=1).pack();Tk().mainloop() work?
Conor O'Brien

@ConorO'Brien testing
Mr. Xcoder

@ConorO'Brien no. It produces two different tkinter windows. One with the text field, one empty. It doesn't seem right to me.
Mr. Xcoder

Do you need the show=?
Esolanging Fruit

@Challenger5 Yes, we do need the show=
Mr. Xcoder

1

Groovy, 77 73 bytes

{new java.awt.Frame(){{add(new javax.swing.JPasswordField());visible=1}}}

This is an anonymous closure, with 0 required inputs.

Ungolfed:

{
    new java.awt.Frame() {
        {
            add(new javax.swing.JPasswordField())
            visible=1
        }
    }
}

Edit 1 (-4 bytes): Component#visible can be directly accessed, read more here.


1

Micro, 35 bytes

"":i{L46c:\
i~+:i
i10c=if(,a)}a
i:\

explination:

"":i                      create new blank string 'i'
    {                          begin input loop
     L                         input a character
      46c:\                    display ascii char #46 (.) (it is popped, leaving the input char from 'L'
           i~+:i               push i, flip i and the char around, concatinate them, and store that to i
                i10c=if(,a)}a  OK, a lot happens here, if a NL is in i, the loop terminates, and the final i:\ will display the input


1
That's a pretty good first attempt at a language! +1
MD XF

1

BF, 24 bytes

++++++[->++++++<],[>.<,]

Works with bf.doleczek.pl. You can send a zero char to the program with Ctrl+Z.

Alternative solution:

BF, 1 byte

,

This is a very tongue-in-cheek solution. My terminal is 0 characters wide, so please don't enter any passwords longer than that.


Whoa... not bad!
MD XF

@MDXF Are you referring to the 24 byte one or the 1 byte one?
Esolanging Fruit

Clearly the 24-byte one. I completely forgot that printing \b is a thing. :P
MD XF

@MDXF What do you mean by that? \b is unprintable anyways.
Esolanging Fruit

No I mean your solution uses \b to override the input, correct?
MD XF

1

PowerShell, 12 bytes

Read-Host -a

This reads input from host and, with the -a flag treats it as a securestring/password. In the ISE it pops up a message box which has a similar behavior since the ISE doesn't allow keypress capture.

PS C:\Windows\system32> Read-Host -a
************

1

QBasic, 48 bytes

DO
a$=INPUT$(1)
IF ASC(a$)=13THEN END
?"*";
LOOP

INPUT$(1) reads the next character from keyboard input. (This can include things like tab, backspace, and escape, but since the OP didn't say anything about those I'll assume we don't have to worry about them.) If the character is \r (ASCII 13), terminate the program; otherwise, print * without a newline. Repeat ad infinitum.


1

Perl + Bash, 30 bytes

print"*"while$|=1+`read -sn 1`

c is *, uses read from bash, so isn't a pure Perl solution.


1

brainfuck, 21 bytes

-[+>,[<->+[<.>[-]]]<]

Last one, I promise. No input = -1, end of input = 0

How it Works

-[  Enters the loop
  +>, Get input
     [<->+ If not end of input it create the ÿ character and check if the input is not -1
          [<.>[-]]] If there was input, print the ÿ character. 
                    <] Exit the loop if end of input

Your code is missing a closing bracket. And why do you make it that complicated? A simple "print a 'ÿ' for every input character" could be accomplished with a simple ,[>-.,]
Dorian

@Dorian The bracket was a mistake, but the complexity arises from having to handle both no input and end of input
Jo King

0

QBIC, 44 bytes

{X=inkey$~X<>@`|~X=chr$(13)|_X\Y=Y+@*`_C?Y

Explanation

{            DO
X=inkey$     Read a char, set it to X$
             Note that INKEY$ doesn't wait for keypress, but simply sends out "" if no key was pressed.
~X<>@`|      IF X$ has a value THEN
~X=chr$(13)| IF that value is ENTER
_X           THEN END
\            ELSE
Y=Y+@*`      append a literal * to Y$
_C           Clear the screen
?Y           Display Y$ (having 1 * for each char entered)
             The IF's and the DO-loop are auto-closed at EOF{            DO
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.