왜 거꾸로 쓰여진 이 코드가 "Hello World!"를 인쇄하는가?
내가 인터넷에서 찾은 몇 가지 코드:
class M{public static void main(String[]a){System.out.print(new char[]
{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
이 코드는 인쇄된다.Hello World!
화면에 띄워라. 여기 보이는 것처럼.나는 똑똑히 알 수 있다.public static void main
쓰여졌지만, 거꾸로 되어 있다.이 코드는 어떻게 작동하는가?어떻게 컴파일할 수 있지?
편집: ItellIJ에서 이 코드를 시도했는데 잘 작동한다.그러나 어떤 이유로 cmd와 함께 메모장++에서는 작동하지 않는다.나는 아직 그것에 대한 해결책을 찾지 못했어. 그러니 만약 누가 해결한다면, 아래에 언급해.
여기에 코드 표시 방식을 바꾸는 보이지 않는 문자가 있다.를 빈 수 ""
() 유니코드 탈출로 대체하여 효과를 제거하고 컴파일러가 보는 순서를 밝힌다.
복사 붙여넣기의 결과는 다음과 같다.
"class M\u202E{public static void main(String[]a\u202D){System.out.print(new char[]\n"+
"{'H','e','l','l','o',' ','W','o','r','l','d','!'});}} "
소스 코드 문자는 이 순서로 저장되며, 컴파일러는 이들을 이 순서에 있는 것으로 취급하지만, 다르게 표시된다.
을 참고:\u202E
오른쪽에서 왼쪽으로 오버라이드되는 문자(문자)는 모든 문자를 오른쪽에서 왼쪽으로 표시하도록 강제되는 블록을 시작하고\u202D
왼쪽에서 오른쪽으로 덮어쓰기, 모든 문자가 왼쪽에서 오른쪽으로 강제로 정렬되는 중첩된 블록을 시작하여 첫 번째 덮어쓰기를 재정의함.
에르고, 원래 코드를 표시하면class M
정상적으로 표시되지만\u202E
거기에 있는 모든 것의 표시 순서를 반대로 하다.\u202D
, 모든 것을 다시 뒤집는 것. (공식적으로, 모든 것부터)\u202D
라인 터미네이터는 두 번 역전되며, 한 번으로 인해\u202D
그리고 한 번은 나머지 글들이 그 때문에 뒤바뀌었다.\u202E
, 그래서 이 텍스트가 끝 대신 줄 가운데로 나타나는 것이다.)다음 라인의 방향성은 라인 종단기로 인해 첫 번째 라인과 독립적으로 처리되므로{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
정상적으로 표시됨.
전체(극히 복잡한, 수십 페이지 길이의) 유니코드 양방향 알고리즘에 대해서는 유니코드 표준 부속서 #9를 참조한다.
유니코드 양방향 알고리즘 때문에 다르게 보인다.유니코드 양방향 알고리즘이 이 두 메타택터 사이에 중첩된 문자의 시각적 외관을 변경하기 위해 사용하는 RLO와 LRO의 보이지 않는 두 개의 문자가 있다.
결과는 시각적으로는 역순으로 보이지만 실제 기억 속 문자는 역순으로 나타나지 않는다는 것이다.여기서 결과를 분석할 수 있다.자바 컴파일러는 RLO와 LRO를 무시하고 공백으로 취급할 것이며, 그래서 코드가 컴파일되는 것이다.
주 1: 이 알고리즘은 텍스트 편집기와 브라우저에 의해 LTR 문자(영어)와 RTL 문자(예: 아랍어, 히브리어)를 동시에 시각적으로 표시하기 위해 사용된다. 따라서 "양" 방향.당신은 유니코드의 웹사이트에서 양방향 알고리즘에 대해 더 많이 읽을 수 있다.
참고 2: LRO와 RLO의 정확한 거동은 알고리즘 섹션 2.2에 정의되어 있다.
캐터터U+202E
오른쪽에서 왼쪽으로 코드를 미러링한다. 하지만 그것은 매우 영리하다.M부터 숨겨져 있고
"class M\u202E{..."
내가 어떻게 이면의 마법을 발견했을까?
음, 처음에는 "다른 사람을 잃는 것은 일종의 농담이다"라는 질문을 보았지만, 그 후 IDE("IntelliJ")를 열어 수업을 만들고 코드를 넘겨서...그리고 그것이 편찬되었다!!!그래서 더 잘 살펴보니 '공공의 정적 공백'이 뒤로 물러나는 것을 보고 커서를 들고 그곳에 가서 몇 자 지웠다...그리고 무슨 일이 일어나나요?차들이 뒤로 지워지기 시작했어 그래서, 난 음... 드물게...그걸 실행해야 해...그래서 프로그램 실행을 진행하지만, 먼저 프로그램을 저장해야 했다...그때 내가 찾았어!내 IDE가 어떤 char에 대해 다른 인코딩이 있다고 해서 파일을 저장할 수 없었고, 어디에 있는지 알려줘서 구글에서 그 일을 할 수 있는 특별한 chars에 대한 연구를 시작했는데, 그게 다야.)
에 대해 조금.
유니코드 양방향 알고리즘U+202E
관련, 간략한 설명:
유니코드 표준은 논리 순서라고 알려진 메모리 표현 순서를 규정한다.텍스트를 가로줄로 표시하면 대부분의 스크립트는 왼쪽에서 오른쪽으로 문자를 표시한다.그러나 디스플레이에 표시되는 가로 텍스트의 자연적인 순서가 오른쪽에서 왼쪽인 여러 스크립트(아랍어 또는 히브리어 등)가 있다.모든 텍스트가 수평 방향이 동일하면 표시 텍스트의 순서는 명확하다.
그러나 이러한 좌우 스크립트는 왼쪽에서 오른쪽으로 쓰여진 숫자를 사용하기 때문에, 텍스트는 실제로 양방향으로, 즉 오른쪽에서 왼쪽으로와 왼쪽에서 오른쪽으로의 텍스트가 혼합된 것이다.자리수 외에도 영어 등 대본의 임베디드어가 왼쪽에서 오른쪽으로 쓰이면서 양방향 텍스트도 만들어진다.명확한 명세가 없으면 텍스트의 수평 방향이 균일하지 않을 때 표시되는 문자의 순서를 결정할 때 모호성이 발생할 수 있다.
이 부속문서는 양방향 유니코드 텍스트의 방향성을 결정하는 데 사용되는 알고리즘을 설명한다.알고리즘은 현재 다수의 기존 구현에 의해 채택된 암묵적 모델을 확장하고 특별한 상황에 대한 명시적 포맷 문자를 추가한다.대부분의 경우 정확한 디스플레이 순서를 얻기 위해 텍스트와 함께 추가 정보를 포함할 필요가 없다.
그러나 양방향 텍스트의 경우 암묵적 양방향 순서가 이해 가능한 텍스트를 생성하기에 충분하지 않은 상황이 있다.이러한 경우를 처리하기 위해 렌더링 시 문자 순서를 제어하기 위해 최소 방향 형식 지정 문자 집합을 정의한다.이것은 읽기 쉬운 교환을 위해 표시장치 순서를 정확하게 제어할 수 있고 파일 이름이나 라벨과 같은 간단한 항목에 사용되는 일반 텍스트가 항상 표시하기 위해 올바르게 정렬될 수 있도록 한다.
왜 이런 알고리즘을 만들까?
bidi 알고리즘은 오른쪽에서 왼쪽으로 차례로 아라비아어나 히브리어 문자를 렌더링할 수 있다.
언어사양의 3장은 자바 프로그램에 대해 어휘 번역이 어떻게 이루어지는지를 상세히 기술함으로써 설명을 제공한다.이 질문에 가장 중요한 것은:
프로그램은 유니코드(제3.1조)로 작성되지만, 어휘 번역(제3.2조)이 제공되어 유니코드가 탈출(제3.3조)하는 것은 ASCII 문자만을 사용하여 어떤 유니코드 문자도 포함할 수 있다.
그래서 프로그램은 유니코드 문자로 쓰여져 있고, 저자는 이를 이용하여 탈출할 수 있다.\uxxxx
파일 인코딩이 유니코드 문자를 지원하지 않는 경우, 이 경우 적절한 문자로 변환된다.이 경우에 나타나는 유니코드 문자 중 하나는\u202E
수 있다 코드 조각에는 보이지 않지만, 브라우저의 인코딩을 바꾸려고 하면 숨겨진 문자가 나타날 수 있다.
따라서 어휘 번역은 다음과 같은 계급 선언으로 귀결된다.
class M\u202E{
, 는 즉, 스래스톱은 는이라는 뜻이다.M\u202E
명세서는 이를 유효한 식별자로 간주한다.
Identifier:
IdentifierChars but not a Keyword or BooleanLiteral or NullLiteral
IdentifierChars:
JavaLetter {JavaLetterOrDigit}
"Java 문자 또는 숫자"는 메소드를 나타내는 문자다.
Character.isJavaIdentifierPart(int)
진실로 돌아오다
이것은 실제로 유니코드 양방향 지원 때문이다.
U+202E 오른쪽에서 왼쪽으로 오버라이드
U+202D 왼쪽에서 오른쪽으로 오버라이드
그래서, 그것들은 좀 까다로운 캐릭터들이야.그것들은 실제로 좌우 언어 지원을 위해 정의된다.진짜 코드는.
class M<U+202E>{public static void main(String[]a<U+202D>){System.out.print(new char[]
{'H','e','l','l','o',' ','W','o','r','l','d','!'});}}
(cmd.exe에 붙여넣음으로써 얻음).이 대답이 어떻게 작동하는지 알아내는 데 도움이 되기를 바란다.
참조URL: https://stackoverflow.com/questions/43943699/why-does-this-code-written-backwards-print-hello-world
'programing' 카테고리의 다른 글
Nuxt vuex 상태 메뉴목록:구성 요소에서 정의되지 않음 (0) | 2022.04.21 |
---|---|
여러 아키텍처에 최적화된 NDK 코드를 생성하시겠습니까? (0) | 2022.04.21 |
형식화된 메시지, 개체 배열, 예외를 기록하는 방법 (0) | 2022.04.21 |
왜 우리는 국가 관리를 위해 돌연변이, 세터, 게이터가 필요한가? (0) | 2022.04.21 |
사용자 지정 구성 요소에 사용할 경우 v-model과 .sync의 차이점 (0) | 2022.04.21 |